1 of 1 people found this helpful
Application server is treated as a resource manager so that it could participate in a two phase commit protocol of the externally initiated transaction. Thus, we use TransactionImported to create a subordinate transaction. During the creation process Xid is passed through from the Resource Adapter to the subordinate transaction and is reused further.
It is mentioned in the JTA spec (JTA 1.2 bottom of page 16), that each of RM's internal units of work is part of exactly one branch. So since the subordinate transaction is acting as a resource manager in the external transaction, it makes sense for the local XA resources to be enlisted under the same branch qualifier.
Thanks a lot Gytis for explanation. I do understand the process. Nevertheless I've still got a doubt what happens e.g. for some databases that requires different connections being considered as separate branches. I would like try it. I will let you know what is outcome of that.
I'm back with my doubt. I've tried to run the following scenario
- Inflow message starts defines a transaction and passing inflow message through JCA layer to container/MDB
- I've configured two datasources which points to the same database machine (PostgreSQL 9.4) and each one works with different database
- onMethod uses both datasources - does changes in a table in both databases
- jdbc prepare call fails with org.postgresql.util.PSQLException: ERROR: prepared transaction with identifier 
That way using the same Xid for two calls of the same RA could cause a trouble (e.g. as mentioned here). Is my settings wrong? Or is there some workaround for this?
2016-05-16 11:48:15,790 WARN [com.arjuna.ats.jta] (default-threads - 1) ARJUNA016045: attempted rollback of < 4660, 64, 64, 1270010000100042000000000000000000000000000000000000000000000000000, 1270010000100042000000000000000000000000000000000000000000000000000 > (XAResourceWrapperImpl@54475a0d[xaResource=org.jboss.jca.adapters.jdbc.xa.XAManagedConnection@60d22655 pad=false overrideRmValue=null productName=PostgreSQL productVersion=9.4.7 jndiName=java:jboss/xa-datasources/CrashRecoveryDS1]) failed with exception code XAException.XAER_NOTA: org.postgresql.xa.PGXAException: Error rolling back prepared transaction at org.postgresql.xa.PGXAConnection.rollback(PGXAConnection.java:435) at org.jboss.jca.adapters.jdbc.xa.XAManagedConnection.rollback(XAManagedConnection.java:346) at org.jboss.jca.core.tx.jbossts.XAResourceWrapperImpl.rollback(XAResourceWrapperImpl.java:196) at com.arjuna.ats.internal.jta.resources.arjunacore.XAResourceRecord.topLevelAbort(XAResourceRecord.java:369) at com.arjuna.ats.arjuna.coordinator.BasicAction.doAbort(BasicAction.java:2999) at com.arjuna.ats.arjuna.coordinator.BasicAction.doAbort(BasicAction.java:2978) at com.arjuna.ats.arjuna.coordinator.BasicAction.phase2Abort(BasicAction.java:1961) at com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.SubordinateAtomicAction.doRollback(SubordinateAtomicAction.java:196) at com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.TransactionImple.doRollback(TransactionImple.java:219) at com.arjuna.ats.internal.jta.transaction.arjunacore.jca.XATerminatorImple.prepare(XATerminatorImple.java:250) at org.jboss.as.test.jbossts.crashrec.jca.rar.TestResourceTxnWorkUnit.run(TestResourceTxnWorkUnit.java:86) at org.jboss.jca.core.workmanager.WorkWrapper.run(WorkWrapper.java:223) at org.jboss.threads.SimpleDirectExecutor.execute(SimpleDirectExecutor.java:33) at org.jboss.threads.QueueExecutor.runTask(QueueExecutor.java:808) at org.jboss.threads.QueueExecutor.access$100(QueueExecutor.java:45) at org.jboss.threads.QueueExecutor$Worker.run(QueueExecutor.java:828) at java.lang.Thread.run(Thread.java:745) at org.jboss.threads.JBossThread.run(JBossThread.java:320) Caused by: org.postgresql.util.PSQLException: ERROR: prepared transaction with identifier "4660_fwAAAQAAAAABAAAAKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==_fwAAAQAAAAABAAAAKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" does not exist at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2270) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1998) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255) at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:570) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:406) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:334) at org.postgresql.xa.PGXAConnection.rollback(PGXAConnection.java:423) ... 17 more
Using JCA (without JBoss Remoting EJB inflow) will enforce the JCA spec mandated constraint of a single immutable Xid during the flow. So if the resource manager thinks its the same RM or not it will still always get the same Xid.
I think to reproduce this one you should set your harness as the EIS and just use one XAR on the JBoss side. Then call commit(false) (even though you have only one XAR as the EIS simulated could have other RM/TMs). This will go through 2PC and allow you to simulate the scenario.
Hope it helps,
thank you for clarification. I've got it. If anybody uses JCA inflow transaction he has to be aware of this limitation.