我有一个war
服务,其中有三个我的自定义jar
。我的每个jar
都使用一个自我数据源。因此,我在JBoss配置中定义了三个不同的数据源,并在其中关联了相应的persistence.xml。我可以将其描述如下:
我们在这里提供三种服务:SM,RE和RA,每个都有自己的数据源。 SM和RE使用数据源进行读写,但是RA只是从DB读取。这些与数据源交互的顺序以图片上箭头附近的数字表示。因此,最初,SM从DB读取数据,最后,RE向DB写入数据。
我的问题是:如果我想在一次事务中同时向两个数据源写入数据,该怎么办?
有两个可能的答案,但都不能令我满意:
当我要写入数据时,请同时使用SM和RE中JBoss的UserTransaction
,并手动处理事务的开始然后提交。但是在这里,我有太多其他问题,例如WFTXN0001: A transaction is already in progress
,即使我以前从未开始过。我不明白它是如何工作的,也找不到简明的文档或阐明UserTransaction
用法的示例。因此,第一个答案是“太难使用了,让我们再使用其他东西”。
完全拒绝分布式事务,并将更改顺序提交到两个数据库。我知道这是一个陷阱,但是如果我避免使用任何事务,然后将下一个属性插入WildFly配置,则它可以工作:
<system-properties>
<property name="com.arjuna.ats.arjuna.allowMultipleLastResources" value="true"/>
</system-properties>
有效!但是,日志中有一条警告消息:
16:09:23,581 WARN [com.arjuna.ats.arjuna] (default task-1) ARJUNA012141: Multiple last resources have been added to the current transaction. This is transactionally unsafe and should not be relied upon. Current resource is LastResourceRecord(XAOnePhaseResource(LocalXAResourceImpl@dbaabf3[connectionListener=767c209 connectionManager=78f5d4e2 warned=false currentXid=< formatId=131077, gtrid_length=29, bqual_length=36, tx_uid=0:ffff0ac03a90:74af3477:5c7fb46c:343, node_name=1, branch_uid=0:ffff0ac03a90:74af3477:5c7fb46c:35f, subordinatenodename=null, eis_name=java:/db3 > productName=PostgreSQL productVersion=9.6.2 jndiName=java:/db3]))
...
16:09:23,631 WARN [com.arjuna.ats.arjuna] (default task-1) ARJUNA012141: Multiple last resources have been added to the current transaction. This is transactionally unsafe and should not be relied upon. Current resource is LastResourceRecord(XAOnePhaseResource(LocalXAResourceImpl@57a1383c[connectionListener=5ddce49c connectionManager=c66a93f warned=false currentXid=null productName=PostgreSQL productVersion=9.6.9 jndiName=java:/db2]))
我想逃避这些可怕的消息,但是我不能,因为JBoss限制了我。也许您知道如何通过其他方式轻松地在JBoss上使用分布式事务?
谢谢。
P.S。我不使用Spring。我被禁止使用。
答案 0 :(得分:0)
嗯,不使用Spring并不是一件坏事。
您的图有一个WAR文件,该文件可以通过各种jar访问三个数据库。您正在使用什么持久性服务(如果有)?
您的交易分界是什么?您应该在相同的事务上下文中进行数据库调用。您不需要启动用户事务。如果您在Web服务类上使用“ @Transactional”注释,则JBoss将启动一个事务,并且数据库访问应加入该事务。