3 Replies Latest reply on Jun 27, 2017 7:37 AM by Ondra Chaloupka

    What are the correct return codes for commit/prepare not existing subordinate transaction

    Ondra Chaloupka Apprentice

      Hi,

       

      I'm investigating on a potential issue of integration Narayana/WFTC/WildFly and I would like kindly ask you for help what is the expected behaviour here. I would like to know how the transaction manager should behave when EIS system calls RAR XATerminator.commit/prepare and the subordinate transaction was already rolled-back.

       

      The scenario is following
      * inflow transaction is started takes long time
      * transaction reaper rolls back the transaction
      * RAR calls XATerminator.prepare
      * RAR calls XATerminator.commit
      * RAR calls XATerminator.prepare (second call)
      * RAR calls XATerminator.commit (second call)

       

      Now, I would expect that the prepare call should be answered by XA_RBROLLBACK (informing the EIS that transaction was spontaneously rolled back), then on commit and subsequent calls the XAER_NOTA (informing EIS that already the txn is not known).

      The current behaviour in WFLY/WFTC upstream is following

       

      JTS:
      * first prepare: XAER_NOTA; at doPrepare txn is null thus TwoPhaseOutcome.INVALID_TRANSACTION[1] is returned which is transalted to XAER_NOTA by WFTC[2]
      * first commit: XA_HEURMIX, at doCommit txn is null and ActionStatus.H_HAZARD is returned[3], which is translated to HeuristicMixedException being thrown [4]
      * second prepare: XAER_NOTA; the same scenario as first prepare
      * second commit: XA_HEURMIX, the same scenario as first commit

       

      JTA
      * first prepare: RBROLLBACK; at doPrepare status is defined as ABORTED and TwoPhaseOutcome.PREPARE_NOTOK is returned[5] which WFTC transalates to call rollback and returns RBROLLBACK[7]
      * first commit: XA_HEURRB; at doCommit the phase2Commit[8] reports heuristics and next the HeuristicRollbackException is thrown[9]
      * second prepare: RBROLLBACK; the same scenario as first prepare
      * second commit:  XA_HEURRB, the same scenario as first commit

       

      Then I'm not sure what should be the expected behavior - what are error codes that should be  returned. By me seems logic to get returned RBROLLBACK - XAER_NOTA - XAER_NOTA - XAER_NOTA... Is it so? Should be that different? Could be some diffference between jta and jts behaviour?

       

      For example jhalliday would you have a minute to check this?

       

      Thank you in advance!
      Ondra

       


      [1] https://github.com/jbosstm/narayana/blob/master/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/SubordinateAtomicTransaction.java#L96
      [2] https://github.com/wildfly/wildfly-transaction-client/blob/master/src/main/java/org/wildfly/transaction/client/provider/jboss/JBossLocalTransactionProvider.java#L441
      [2] https://github.com/jbosstm/narayana/blob/master/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/SubordinateAtomicTransaction.java#L115
      [4] https://github.com/jbosstm/narayana/blob/master/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/TransactionImple.java#L179
      [5] https://github.com/jbosstm/narayana/blob/master/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/subordinate/SubordinateAtomicAction.java#L128
      [6] https://github.com/jbosstm/narayana/blob/master/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/subordinate/TransactionImple.java#L114
      [7] https://github.com/wildfly/wildfly-transaction-client/blob/master/src/main/java/org/wildfly/transaction/client/provider/jboss/JBossLocalTransactionProvider.java#L428
      [8] https://github.com/jbosstm/narayana/blob/master/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/subordinate/SubordinateAtomicAction.java#L159
      [9] https://github.com/jbosstm/narayana/blob/master/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/subordinate/TransactionImple.java#L156

        • 1. Re: What are the correct return codes for commit/prepare not existing subordinate transaction
          Tom Jenkinson Master

          The second prepare is wrong and a protocol error from the RAR, XA does not allow for that. You can see it in the state tables in the XA spec and xa_prepare has not concept of XA_RETRY (only allowed from commit, complete and start)

           

          In terms of JTS returning XAER_NOTA and JTA returning RBROLLBACK for the first prepare. IMO either is correct. AFAIUI a resource manager pre-prepare is fine to go away and do what it wants to the branch. Similarly the difference in the xa_commit. JTS must be compliant with OTS as well as JTA/XA and so that restricts the knowledge it can have locally of the transaction state and the exception types it can use. For a bit of context why the differences can happen, JTS cleanup is somewhat more aggressive as it cannot know it will be contacted again outside of the OTS whereas the JTA version can keep the reference to the transaction in memory so we can know it's state.

          2 of 2 people found this helpful
          • 2. Re: What are the correct return codes for commit/prepare not existing subordinate transaction
            Michael Musgrove Master

            The EIS treats the application server like a resource manager so the XA spec provides the expected behaviour. Section 3.6 covers your scenario:

            Unilateral RM Action

            An RM can mark a transaction branch as rollback-only any time except after a

            successful prepare. A TM detects this when the RM returns a rollback-only return

            code. An RM can also unilaterally roll back and forget a branch any time except after a

            successful prepare. A TM detects this when a subsequent call indicates that the RM

            does not recognise the XID. The former technique gives the TM more information.

            If a thread of control terminates, an RM must dissociate and roll back any associated

            transaction branch. If an RM experiences machine failure or termination, it must also

            unilaterally roll back all branches that have not successfully prepared.

             

            So the XATerminator#call should either return one of the RB* error codes or XAER_NOTA. Therefore the JTS and JTA implementations are allowed to return different codes so long as the actual code is one of these.