Java-Transaction: 理解 XADataSource

本人博客已经迁移至 www.shangyang.me 欢迎大家访问

 

Reference Site:

atomikos site: http://www.atomikos.com/Documentation/ConfiguringJdbc

                       http://www.atomikos.com/Documentation/WebHome

JTA : http://java.sun.com/javaee/5/docs/tutorial/doc/bnciy.html#bnciz

XA:   http://jroller.com/pyrasun/category/XA

 

简单总结

   XADataSource 通过四步Start, End, Prepare, Commit 保证 多个数据源的事务完整性. 它主要额外提供了Prepare这个过程. 那么提供这个Prepare过程有什么用呢?这个过程有两个很重要的步骤, 1. 询问每个DataSource 你准备好了Commit吗? 在这个期间,如果有任何一个Datasource返回No,所有事务回滚. 2. 向系统内写日志.(这一步对于在Commit的时候产生异常进行灾难性的恢复相当关键)。这里需要强调的是,对于XADataSource,JTA的事务管理范围包括 Start, End, Prepare 这三个步骤.

 

如果我们有2个数据源数据源A数据源B, 来讨论如下几种事务失败的情况.

   1. 在 Start <--> End(Java Transaction boundary) 之间, 凡是有任何异常,均可以正常回滚.

 

   2. 在 Prepare 的时候出错, Java 的业务逻辑 处理完成, XADataSource现在会询问所有的 DataSource "are you ready to commit", 如果任何一个DataSource说"No", 所有DataSource的事务全部回滚.

       在 项目开发的时候,遇到过一个很有趣的例子,  两个数据源 远程MQ Server + 本地DB2 DataBase, 用的atomikos JTA.  这里,我故意把atomikos的XADataSource 换成了Hibernate 的DataSource,写了一段很简单的程序,先执行Database 的存取操作,然后将相关数据发送给MQ,我故意在程序执行的最后(随便写了段System.out.println()语句) 处打了个断点,然后用Debug模式执行到该断点处,然后我扒开网线,这个时候实际上MQ已经失效了,然后让程序继续执行,最后MQ事务显然失败,但是数据库的事务却提交了. 这里的问题很明显,首先第一,我没用XADataSource,而用的Hibernate的DataSource,所以不会有Prepare这一步。第二,这个例子中,Start <--> END 已经执行完成,对于不是XADataSource的 JTA会直接到 Commit。而这步实际上就是在Commit 的时候出的错. 在JTA的范围之外了,所以整个事务回滚不了.  如果我们将Hibernate的DataSource换成atomikos的XADataSource,然后用相同的操作执行上面的步骤,MQ和DB2事务都失败. 这正是因为在Commit之前会有一步Prepare的过程,XADataSource会询问 MQ Server 和 DB2 DataSource 你们准备好了吗?而此时,MQ会说NO,所以整个事务回滚。这里,我们可以看到XADataSource 的必要性。

 

   3. 在Commit 的时候出错. 这步就是灾难性的一步了,也是XADataSource最棘手的地方了。试想,JTA执行过程中一切成功,并且在Prepare过程的时候,所有的数据源都回答OK。最后某个DataSource在Commit自己的数据的时候不幸出错. 那么此时该如何解决呢? 这里普片的做法就是在Prepare的时候,让XADataSource写日记记录数据提交的详细记录。那么是如何操作的呢? XADatasource会针对每个 XADataSource实例 记录一个编号, 在Prepare的时候会针对这个XADataSource实例写日志,并且保留Commit失败时候的日志,如果Commit的时候发生异常 (我们知道,这步已经是JTA事务管理之外的了,换句话说,这里是XADataSource 的JTA 已经不可能回滚的了),之后 atmokios 根据该失败的XADataSource实例日志 会定期检查对应处理失败的数据源是否恢复正常,如果恢复正常,那么它会根据日志将进行再次提交,直到成功为止。 但是现在并不是任何 XADataSource 的 Provider 都提供了Prepare()过程写日志的功能,有些 仅仅是商业版本的才会提供。或许是因为这步是最棘手也是最难实现的的部分吧.

  

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值