首页 > 代码库 > JAVA分布式事务小结

JAVA分布式事务小结

  分布式事务处理(  Distributed Transaction Processing  ,  DTP  )涉及多个分布在不同地方的数据库,但对数据库的操作必须全部被提交或者回滚。只要任一数据库操作时失败,所有参与事务的数据库都需要回滚。

  举个例子,A服务部署在tomcat上,执行insert a并调用B和C接口,   B服务部署在weblogic上,执行insert b, C服务部署在Nginx,执行insert c。 现在要执行A,并且在执行到insert c时更新失败, 分布式事务的要求是insert a 和 insert b要进行事务性回滚。

  在JAVA中要想处理分布式事务,需要使用JTA。JTA需要有web服务器进行支持。 (补充一点:web服务器为什么有开源的有收费的,有好的有坏的,其中最为重要的一点就是对事务的处理能力, 开源的J2EE服务器在这一点上是跟weblogic、webSphere等商业应用服务器没法比的。)

  Open  组织定义的分布式事务处理模型X/Open DTP  模型(1994)包括应用程序(  AP  )、事务管理器(  TM  )、资源管理器(  RM ,即数据库 )、通信资源管理器(  CRM  )四部分。而 XA 是 X/Open DTP 定义的事务管理器与数据库之间的接口规范(即接口函数),事务管理器用它来通知数据库事务的开始、结束以及提交、回滚等。

  XA  接口规范使用两阶段提交协议(2-PC协议)来完成一个全局事务,保证同一事务中所有数据库同时成功或者回滚。
  两阶段提交协议假设每个数据库点都存在一个write-ahead log,每一次的write请求都是先记log后才真正执行写入。

  两阶段提交需要有个中间协调人。在 Java 中只有 JTA 才能支持两阶段提交,而这个中间协调人就是 J2EE 应用服务器。

  两个阶段:

  1、准备阶段。各数据库在执行完 INSERT 后,J2EE 应用服务器在收到提交指令,这时通知各数据库进行事务提交准备。数据库在收到响应后,进行准备工作,基本上是一个预提交工作,如果能提交则响应 J2EE 应用服务器是能成功提交的,如果无法提交则响应 J2EE 应用服务器是无法提交的。

  2、J2EE 应用服务器在收集到所有的响应之后进行判断,如果在第一阶段收到的信息都是可提交的,那么就通知所有的数据库进行提交;如果在第一阶段收到的信息有一个是无法提交的,那么就通知所有的数据库进行回滚操作。

  以下一版描述转自wdwbw‘s blog:

  第一阶段为提交请求阶段(Commit-request phase):
   1. 事务管理器给所有数据库发query to commit消息请求,然后开始等待回应;
   2. 数据库如果可以提交属于自己的事务分支,则将自己在该事务分支中所做的操作固定记录下来(在undo log和redo log中各记一项);
   3. 数据库都回应是否同意提交的应答。
  第二阶段为提交阶段(Commit phase):
  如果事务管理器收到的所有回应都是agreement,
   1. 事务管理器记日志并给所有数据库发commit消息请求;
   2. 各个数据库执行操作,释放所有该事务相关的锁和资源;
   3. 各个数据库给事务管理器回复;
   4.当收到所有回复,事务管理器结束当前事务

  如果事务管理器收到的任一回应是abort,
   1. 事务管理器记日志并给所有数据库发rollback消息请求;
   2. 各个数据库执行undo操作,释放所有该事务相关的锁和资源;
   3. 各个数据库给事务管理器回复;
   4.当收到所有回复,事务管理器结束当前事务

 

 

  其他:未决事务的处理: 上述第一阶段完成之后,参与者服务器宕机,导致收不到第二阶段提交或者回滚事务的请求。 此时该参与者的本地事务则处于一种未决状态(in-doubt)。分布式事务采用如下机制处理未决事务:当重启后,对于本机的所有未决事务,参与者会向上级发送查询请求,获取每一个事务最终的结果(提交还是中止),他会得到一个明确的答复进而进行本地事务的提交或回滚。

  

JAVA分布式事务小结