程序中使用JTA及其注意的地方
来源:互联网 发布:数据库应用账户管理 编辑:程序博客网 时间:2024/06/03 16:56
在我的以前的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.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的事务(至少会给出警告)!
- 程序中使用JTA及其注意的地方
- Spring使用中需要注意的地方
- HttpURLConnection使用中需要注意的地方
- scanf使用中注意地方
- poppopupwindow 使用注意的地方
- 使用LuaSocketHttp注意的地方
- setInterval() 使用注意的地方
- access中使用SQL语句需要注意的几个地方
- 在FLEX中使用CSS需要注意的地方
- delphi中使用override需要注意的地方
- Flex中使用全屏设置和需要注意的地方
- VC/MFC中使用RichEdit 要注意的地方
- Tomcat中使用JNDI时需要注意的地方
- vs2010中使用 time_t要注意的地方
- 在SQLite中使用事务 注意的地方!
- Easyui 中dialog使用时要注意的地方
- C#中使用事物需要注意的地方
- MyBatis Migrations使用中需要注意的地方
- Hibernate学习(2)----配置Hibernate
- C#如何实现方法的版本控制?
- XAML 学习(3)
- 我对国内软件行业的看法(二)
- 禁止修改计算机名
- 程序中使用JTA及其注意的地方
- 有些空虚
- 我能算到的阶乘有多大(六)
- XAML 学习(4)
- 22w
- 各地的VPI/VCI
- dojo 0.4 关于 editor2 的使用
- 扎根IE开发拥有自己理想的程序员--张硕
- struts国际化带来的javascript 中文乱码问题