5 Replies Latest reply on May 17, 2016 4:50 AM by Ondra Chaloupka

    How to understand Xid for inflow transaction

    Ondra Chaloupka Master



      Eventually I've got to start working on reproducer for https://issues.jboss.org/browse/JBTM-2579 (Throw XAException in XATerminator::commit if a wrapped resource fails transiently). I fight a little bit with jca inflow transaction contract. Currently I do not understand what is way how TM works with Xid.

      I do understand that EIS pass Xid information to TM through ExecutionContext. I process work in MDB where I enlist two mock XA resources.

      During enlistment the both resources receives the same Xid when XAResource.enlist is called. There is this code https://github.com/jbosstm/narayana/blob/master/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/TransactionImple.java#L607 which by formatId returns the same Xid. The formatId is deliberately different from Narayana's one.

      Now my doubt. Even if call XAResource.isSameRM returns false (neither way why false is returned, I mean this could be enforced e.g. on JCA layer) the TM call of XAResource.enlist will provide the same branchId for the XAResource. Is that correct? Whole inflow transaction is considered being under one branchId?

      My wrong understanding here is I though that each transaction resource if is not under the same RM is different by branch id.


      If possible could you please elaborate what is base of transaction inflow handling?


      Thanks a lot for help


        • 1. Re: How to understand Xid for inflow transaction
          Gytis Trikleris Apprentice

          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.

          1 of 1 people found this helpful
          • 2. Re: How to understand Xid for inflow transaction
            Ondra Chaloupka Master

            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.

            • 3. Re: How to understand Xid for inflow transaction
              Ondra Chaloupka Master

              Hi gytis,


              I'm back with my doubt. I've tried to run the following scenario


              1. Inflow message starts defines a transaction and passing inflow message through JCA layer to container/MDB
              2. I've configured two datasources which points to the same database machine (PostgreSQL 9.4) and each one works with different database
              3. onMethod uses both datasources - does changes in a table in both databases
              4. jdbc prepare call fails with org.postgresql.util.PSQLException: ERROR: prepared transaction with identifier [1]

              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)
                  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


              • 4. Re: How to understand Xid for inflow transaction
                Tom Jenkinson Master

                Hi Ondra,


                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,


                • 5. Re: How to understand Xid for inflow transaction
                  Ondra Chaloupka Master

                  Hi Tom,


                  thank you for clarification. I've got it. If anybody uses JCA  inflow transaction he has to be aware of this limitation.