分布式事务入门篇

本地事务

本地事务,即单体应用中单个线程内对一个数据库的事务提交。例如充值操作,充值成功后订单表状态更新为成功,账户表加钱,对应的数据库更新操作如下。

begin transaction update 订单表 set 状态='成功' where id = 110; update 账户表 set 余额=余额+10 where id = 111; commit

相应的程序代码也很简单:

@Transactional public void update() { update订单表(); update账户表(); }

本地事务示例图如下所示。

本地事务可以保证单体应用内对同一数据库操作的ACID特性,但是对分布在不同物理节点上的服务进行数据操作时,本地事务已经不能满足需求了。

分布式事务

分布式事务,事务操作跨多个服务、多个服务器、多个数据库。简单的说,就是将一次大的数据操作分成很多小操作,而这些小操作分别在属于不同应用的服务器上执行,这些小操作要么都执行成功,要么都失败。

充值成功后的操作在分布式环境下的示例图如下所示。

交易平台远程调用订单系统更新订单状态、远程调用账户系统给账户加钱,这两个操作要么都成功,要么都失败,保证数据的一致性。

XA规范

介绍两阶段提交之前,了解一下XA规范。

XA规范是开放群组关于分布式事务处理(DTP)的规范。规范描述了全局的事务管理器与局部的资源管理器之间的接口。XA规范允许多个资源(如数据库,消息队列等)在同一事务中访问,这样可以使ACID属性跨越应用程序而保持有效。XA使用两阶段提交来保证所有资源同时提交或回滚任何特定的事务。

通俗的意思就是XA规范规定了处理分布式事务的规则,通过两阶段提交保证分布式事务数据的一致性。

两阶段提交

两阶段提交(Two-phase Commit,缩写为2PC),即为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种算法。通常,两阶段提交也被称为是一种协议。

对于分布式系统来说,每个服务节点虽然能够清楚的掌握本身操作的成功与失败,但不能知道其它服务节点相应操作的执行结果。分布式事务中,一个事务往往需要跨多个服务节点,所以,为了保证事务的ACID特性,需要引入一个协调者来掌握所有参与事务的参与者的执行情况,并根据参与者的执行结果来决定是否把一系列操作进行最终的提交。两阶段提交算法简单的描述就是,第一阶段是准备阶段,第二阶段是提交阶段,下面分别详细描述这两个阶段。

第一阶段-准备阶段,过程如下图所示。

具体描述过程如下:

  • 协调者向所有参与者询问是否可以执行提交操作,然后开始等待各参与者节点的响应;
  • 参与者收到询问后开始事务执行的准备工作,如资源锁定、预留资源、将Undo信息和Redo信息写入日志等;
  • 各参与者准备工作完成后,响应协调者。如果参与者的准备工作执行成功,则返回一个"同意"消息;如果参与者准备工作执行失败,则返回一个"中止"消息。

第二阶段-提交阶段,过程如下图所示。

当第一阶段所有参与者响应的消息都是“同意”时:

  • 协调者向所有参与者发送"提交"的请求;
  • 参与者收到提交请求后,完成提交操作,并释放在整个事务期间所内占用的资源;
  • 参与者向协调者响应"完成"消息。
  • 协调者收到所有参与者响应的"完成"消息后,事务完成。

当第一阶段中有参与者响应的消息是“终止”,或有参与者未在超时时间内给出响应,则:

  • 协调者向所有参与者发出"回滚"的请求;
  • 参与者收到回滚请求后,使用之前写入的Undo信息执行回滚,然后释放在整个事务期间所占用的资源;
  • 回滚完成后,参与者向协调者响应"回滚完成"消息;
  • 协调者收到所有参与者响应的"回滚完成"消息后,事务取消完成。

通过上面的描述,可以得出两阶段提交的缺点:

  • 协调者需要和所有参与者进行多次通信,通信时间太长,事务的处理时间变长了;
  • 在这个过程中,需要长时间的锁定资源,导致其它操作阻塞;
  • 协调者出现故障时,容易出现单点故障问题,可能导致数据不一致的问题。

JTA分布式事务

JTA(Java Transaction API)是符合DTP模型的,在JavaEE平台下JTA可以用JTS协作XA的数据源实现两阶段提交,WebLogic、Webshare等主流商用的应用服务器提供了JTA的实现和支持。而Tomcat没有实现,这就需要借助第三方的框架Jotm、Automikos等来实现,两者均支持Spring事务整合。

但是,JTA方式分布式事务存在很严重的性能问题,不适合高并发和高性能要求的场景。大部分高并发服务都在避免使用分布式事务,往往通过其他途径来解决数据一致性问题,后续篇幅将记录如何用消息系统避免分布式事务,解决数据一致性问题。

原文发布于微信公众号 - JavaQ(Java-Q)

原文发表时间:2016-09-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JAVA高级架构开发

为什么微服务一定要有网关?

2、过滤器:在服务网关中可以完成一系列的横切功能,例如权限校验、限流以及监控等,这些都可以通过过滤器完成(其实路由转发也是通过过滤器实现的)。

2780
来自专栏windealli

系统性能的影响因素和优化方向小结

系统性能是系统设计、实施中的重要目标。这里简单小结下影响系统性能的几个常见因素,以及优化方案。

2717

3种方式提升云可扩展性

在亚马逊云服务中部署被盛赞为是一个很好的方式来实现高扩展性并且你只需要支付你所使用的云计算机性能即可。那么,如何从这项技术中获得最佳的扩展性呢?

2587
来自专栏云上大文件传输

为什么不建议在云主机上使用ftp的2个原因

ftp文件传输服务历史源远流长,第一版FTP RFC协议制定于1971年,经过多年的完善、修补,很多80年代出生的IT人的第一次文件传输经历就是通过FTP完成的...

8008
来自专栏前端架构与工程

前端工程化-构建

构建的核心是资源管理。简单说,构建就是把前端工程师开发的源代码进行编译、压缩、打包等一系列操作,最终产出可以直接上线或者可供后端工程师的资源。 构建可以划分为纯...

2896
来自专栏数据库新发现

Sun Cluster工作原理介绍(转)

本章的结构安排是以介绍Sun Cluster中重要的概念为主线。相关的工作原理分布在各个概念的介绍之中。     quorum的概念在分布式系统中经常被用到。...

913
来自专栏逸鹏说道

大公司都有哪些开源项目之新浪

新浪:WeiBo https://github.com/weibocom 1.分布式缓存服务器 memcachedb memcachedb是 一个由新浪网的开发...

38710
来自专栏前端黑板报

你真的了解 Web 缓存体系吗?

很高兴认识大家,之前做过很多分享,今天这次终于讲到正题了。因为之前一直讲自动化运维,其实做这么多年运维,自动化运维没干多少年。这几年很多公司各方面机器数量多了,...

1431
来自专栏网商云

腾讯云cvm--linux结合腾讯云企业邮箱配置mailx

新账号关联我们公司购买腾讯云产品,有优惠哦!联系电话:13430587834(微信同号)

4894
来自专栏服务端技术杂谈

微服务系列-架构

模块即服务; 微服务使用库,库定义成内存里面的调用,微服务定义成web请求或远程调用; 独立可部署; 接口调用; 缺点是远程调用比本地重很多; 按业务逻辑进行分...

3167

扫码关注云+社区

领取腾讯云代金券