下图是我目前一个项目中的应用场景和问题描述,请各位大侠指点!!
说明:如果大家看到的图片是个红叉,请右键点击显示图片即可(不知道是论坛的问题还是图片太大)。
[该贴被javaRwx于2010-03-19 10:03修改过]
无论你在Spring中还是在EJB的无态bean中使用事务,都属于JTA事务。statless session bean缺省是激活JTA事务的。
关键问题是:你的Spring使用的JTA事务场景要和EJB容器中事务场景一致,比如使用同一个JNDI源也许可以 。
如果不能合并JTA事务场景,也可以从设计上考虑合并一下,比如要么要EJB的无态Bean中的事务,要么完全使用Spring的事务,不过从你这个案例情况看,单单依靠Spring事务已经控制不住了,所以,就放弃这个业务的Spring事务,走向完全用EJB的无态Bean事务吧,效果都是一样。
另外,事务控制很好,会带来性能上的缺陷,看看"CAP定理",JTA事务和数据库事务是保证严格一致性,但是丧失可用性。
[该贴被banq于2010-03-19 10:37修改过]
1、为什么单单依靠Spring控制不住这种场景下的事务(我也测试过,发现的确不行),没有研究过用Spring代替EJB
2、你说的使用同一个JNDI源是指三个EJB服务使用同一个JNDI数据源吗?但是目前的情况是每个EJB都对应着自己的数据库啊
还请多指点!
是啊,JTA事务是跨数据库的,JTA事务是比基于数据库连接的JDBC事务更长的一种事务,可以跨多个数据库JDBC事务,每个JDBC事务的有效范围只能在JDBC连接开始和结束之间,如果需要保证两个JDBC事务的一致性原子性,那么就要使用JTA事务。
JTA事务是通过2PC两段事务来保证跨不同种类数据库操作的ACID的,但是性能很不好,具体使用比较方便,直接从context.lookup所用服务器的JTA的JNDI名称即可,当然,需要首先配置服务器的JTA的JNDI,你可以参考服务器文档。
现在关键是:EJB无态Bean服务调用JDBC时需要一个DataSource,这个JDBC的DATASoource你是从JNDI获得,还是自己定义的数据库连接,如果是从服务器的JNDI获得的,那么就是使用同一个JTA场景了,无论你使用多少EJB,缺省已经激活JTA事务了。
这个DataSource我是通过在Spring中配置数据源的JNDI名字获得,配置如下:
|
我在所有EJB服务中的无状态bean都是通过这种方式获取数据源的,但在EJB的部署描述文件中,并没有对EJB的事务进行配置
[该贴被javaRwx于2010-03-19 11:13修改过]
如果是这样OK,那就直接在EJB里调用其他EJB,应该都处于同一个事务边界内,你断点跟踪一下把,看看启动的是否同一个JTA监控线程。
说一下我的测试步骤:
1、我将EJB服务1、EJB服务2及EJB服务3均部署在不同的weblogic上,分别访问各自的数据库,访问数据库的方式统一使用Spring配置JNDI数据源的方式(在weblogic中配置数据源时,专门选择的oracle.jdbc.xa.client.OracleXADataSource驱动)
2、在EJB服务1中的doRegister方法中分别调用EJB服务2和EJB服务3中的方法实现注册业务,在提交时发现事务仍然没有被控制住
不要通过Spring调。
|
改为统一通过EJB调用,在EJB中获得JNDI datasource:
|
|
现将两个EJB做为附件上传,麻烦板桥大哥给看看,提提意见
两个EJB调用关系说明:
ejb1.jar为主EJB,在ejb1.jar包中的IBoDM_DWLXImpl类中的insertDM_DWLX方法中除了调用本地Dao中的方法向本地数据库插入数据外,同时还调用了ejb2中的方法,向ejb2对应的数据库中插入数据
attachment:
本来应该就是这样吧,数据库插入失败,事务当然回滚啊,还有JTA的时候,事务管理器肯定要根据appserver来配置的。