У меня есть war
сервис с тремя моими заказными jar
внутри. Каждый мой jar
использует собственный источник данных. Итак, у меня есть три разных источника данных, определенные в моей конфигурации JBoss и соответствующий файл persistence.xml, где я к ним отношусь. Я могу изобразить это следующим образом:
Где у нас есть три службы: SM, RE и RA, и у каждого есть собственный источник данных. SM и RE используют источники данных для чтения и записи, но RA просто читает из БД. Порядок этих взаимодействий с источниками данных представлен в виде чисел возле стрелок на рисунке. Итак, изначально SM читает из БД, а в конце RE пишет в БД.
Мой вопрос: что мне нужно использовать, если я хочу в конце записать данные в оба источника данных, но в одну транзакцию?
Есть два возможных ответа, но оба меня не удовлетворяют:
Используйте UserTransaction
от JBoss в SM и RE, когда я хочу записать данные, и вручную обработать начало транзакции, а затем зафиксировать. Но здесь у меня слишком много дополнительных проблем, таких как 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. Мне запрещено его использовать.