程序中使用JTA及其注意的地方

 
在我的以前的 blog 中曾多次谈到了跨数据库的事务(即分布式事务),的确这个方面可能在平时的应用中遇到的不多,但在一些比较大型的项目中或是多系统合作的条件下还是会碰到的。
J2EE 下这个问题的解决有两种方案:一是采用 EJB ,利用容器去管理,我们把针对多个数据库的操作方法放到 session bean 的一个方法中,当和数据库交互产生问题时抛出 EJBException ,通知容器,则可以做到整个事务的回滚,在这里要注意一点的是我们的数据源配置要用 XA 的数据源配置 ( 具体的可以看 Jboss 中的例子 ) ,不过你用普通的数据源也可以做到回滚,但容器在装载应用程序和 EJB 时会给出警告,说明在可能的情况下不能做到事务的整个回滚,所以我们还是用 XA 的数据源比较稳妥。
另一种方法是不用 EJB 容器的自动管理,自己在代码中手动调用 JTA API 来实现分布式事务的管理,要能这样做,首先你使用的 J2EE 服务器要提供 JTA 的实现,数据库和数据库驱动程序都要支持 XA 的事务。我在实践中测试用的是 JBoss4.0.2 SQL Server2000 jtds 1.2 的组合,没有问题。
首先我们要找到容器提供的事务管理器,
InitialContext jndiContext = new InitialContext();
UserTransaction  utx = (javax.transaction.UserTransaction) jndiContext.lookup(
                                          "java:comp/UserTransaction");
当程序找到 UserTransaction 后就可以开始分布式事务了。
try{
utx.begin()
……… // 针对多个数据库的操作
utx.commit();
}
catch(Exception e){
utx.rollback();
}
以上就是通过程序来实现分布式的事务处理。
在这个有几个细节要注意:
一是我们在事务中要处理的数据库的连接的建立要放在 utx.begin( ) 之后,不能建立在事务开始之前,否则事务是会失效的(这个也很好理解,在我上篇 blog 中讲的 XA 事务的实现逻辑中就能找到答案);但特别的是数据库的连接建立要在事务开始之后,但其关闭却不用在事务结束之前,也就是说我在事务中建立的 conn ,可以在事务完成后仍保持连接继续使用,而不是像有些资料所说事务的生命周期一定要长于 conn 的生命周期。
另外一点要注意的是在 JTA 的事务中不能再有 JDBC 的事务,比如在上面 utx.begin( ) 之后,我对一个数据库的操作有多起,那这几起中我再使用 JDBC 的事务,如 conn.commit( ),conn.rollback( ) 等,这是不行的,程序会报错。但当我的 JTA 的事务处理完后,也就是 utx.commit( ) 后再对某个 conn 的操作,我仍可以使用 JDBC 的事务了。也就是说实际上一个XA的连接(XA数据源产出的连接)我完全能将其看作是一个非XA的连接(普通的数据源产生的连接),但是返过来却不能,非XA的连接不能参与JTA的事务(至少会给出警告)!
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值