14

我们正在从 JBoss 6 升级到 JBoss 7。我们的应用程序的性质是每个客户都有一个单独的数据库实例,以及一个所有客户通用的核心配置数据库。我们经常有 EJB 代码,它至少会在一次调用中引用核心数据库和单个客户的数据,甚至是一些经过所有客户的通用后台进程。

在 JBoss 6 中,通过使用 NOT_SUPPORTED 事务属性设置方法,可以毫无问题地处理这个问题。但是,JBoss 7 抱怨这个并出现以下错误:

ARJUNA012140:不允许添加多个最后一个资源。试图添加 LastResourceRecord(XAOnePhaseResource(LocalXAResourceImpl@74bec54d[connectionListener=d3ce980 connectionManager=25b47a05 warn=false currentXid=< formatId=131077, gtrid_length=29, bqual_length=36, tx_uid=0:ffff0a2c28d1:-5a4c1f9a:5046:5046) 1、branch_uid=0:ffff0a2c28d1:-5a4c1f9a:504689c9:14,从属节点名=null,eis_name=unknown eis name >])),但是已经有LastResourceRecord(XAOnePhaseResource(LocalXAResourceImpl@518d0191[connectionListener=1a05d94a connectionManager=135f1cfe warn=false) =< 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, 从属nodename=null, eis未知的eis名称>]))

如果不对不同数据库的每次调用都包装在单独的 EJB 调用和事务中,我们如何才能解决这个问题。有没有办法在 EJB 调用或类似的东西中真正关闭 JBoss 事务管理?

注意:这个问题在赏金开始后根据额外的发现进行了修改,以加强对特定问题的关注并消除其他被排除的可能性。

4

2 回答 2

19

两个建议:

  1. 考虑将数据源更新为其 XA 等效项。这将解决您的所有问题。我怀疑你在这里受阻?
  2. 考虑com.arjuna.ats.arjuna.allowMultipleLastResources在服务器 conf 中设置为 true。这将允许您想要的行为,但不幸的是整个应用程序,而不仅仅是方法。

更新:

我不建议启用多个单阶段资源,因为它会大大削弱您应用程序的事务属性。但是如果你想在 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。

于 2012-09-11T16:40:55.583 回答
10

好的,事实证明,与 JBoss6 不同,就检索数据源的验证逻辑而言,NOT_SUPPORTED 事务仍然是事务。

解决这个问题的方法是使整个 EJB 成为一个 bean 管理的事务:

@TransactionManagement(TransactionManagementType.BEAN)

不幸的是,这限制了一些灵活性,因为有时您宁愿逐个控制此方法,但解决方法并不太痛苦。

于 2012-09-10T19:30:40.360 回答