我们正在从JBoss 6升级到JBoss 7.我们的应用程序的性质是每个客户都有一个单独的数据库实例,以及所有客户共有的核心配置数据库。我们经常使用EJB代码,它至少会在一次调用中引用核心数据库和单个客户的数据,甚至是一些通过所有客户的一般后台流程。
在JBoss 6中,通过使用NOT_SUPPORTED事务属性设置方法,可以毫无问题地处理这个问题。但是,JBoss 7抱怨这个错误:
ARJUNA012140:不允许添加多个最后资源。尝试去 加 LastResourceRecord(XAOnePhaseResource(LocalXAResourceImpl @ 74bec54d [connectionListener = d3ce980 connectionManager = 25b47a05 warned = false currentXid =< formatId = 131077, gtrid_length = 29,bqual_length = 36, tx_uid = 0:ffff0a2c28d1:-5a4c1f9a:504689c9:11,node_name = 1, branch_uid = 0:ffff0a2c28d1:-5a4c1f9a:504689c9:14, subordinatenodename = null,eis_name = unknown eis name>])),但已经 有 LastResourceRecord(XAOnePhaseResource(LocalXAResourceImpl @ 518d0191 [connectionListener = 1a05d94a connectionManager = 135f1cfe warned = false currentXid =< formatId = 131077, gtrid_length = 29,bqual_length = 36, tx_uid = 0:ffff0a2c28d1:-5a4c1f9a:504689c9:11,node_name = 1, branch_uid = 0:ffff0a2c28d1:-5a4c1f9a:504689c9:13, subordinatenodename = null,eis_name = unknown eis name>]))
如果不在单独的EJB调用和事务中包装对不同数据库的每次调用,我们如何解决此问题。有没有办法在EJB调用或类似的东西中实际关闭JBoss事务管理?
注意:此问题在基于额外发现的赏金开始后被修改,以突出对特定问题的关注并删除被排除的其他可能性。
答案 0 :(得分:17)
两个建议:
com.arjuna.ats.arjuna.allowMultipleLastResources
设置为true。这将允许您想要的行为,但遗憾的是整个应用程序,而不仅仅是方法。 <强>更新强>
我不建议启用多个单阶段资源,因为它会大大削弱app的事务属性。但是如果你想在JBoss 7中这样做,你需要修改standalone.xml
并添加:
<system-properties>
<property name="com.arjuna.ats.arjuna.allowMultipleLastResources" value="true"/>
</system-properties>
您现在拥有的系统与没有交易的系统相距不远。它仍然会做什么,是警告你,如果你得到启发式的结果。
如果可以的话,我的建议仍然是使用XA数据源。
更新2:
哦,如果有人来阅读本文,我想补充一点,如果您可以将代码划分为不同的方法,与OP不同,我建议重构代码并使用@TransactionAttribute(REQUIRES_NEW)
创建并行事务。这比打开多个1PC要好,虽然不如打开XA好。
答案 1 :(得分:9)
好的,事实证明,与JBoss6不同,就检索数据源的验证逻辑而言,NOT_SUPPORTED事务仍然是一个事务。
解决这个问题的方法是使整个EJB成为一个bean管理的事务:
@TransactionManagement(TransactionManagementType.BEAN)
这不幸地限制了一些灵活性,因为有时你宁愿控制这种方法,但解决方法并不是太痛苦。