14 Replies Latest reply on Dec 11, 2013 5:21 AM by sebp

    How to get the exception that caused a tx to rollback?

    sebp Newbie

      The com.arjuna.ats.internal.jta.resources.arjunacore.XAOnePhaseResource has the following commit method:

       

      public int commit()
          {
              boolean doForget = false;
      
              try
              {
                  // TODO we don't do an end here yet we do in 2PC. Check!!
      
                  xaResource.commit(xid, true) ;
                  return TwoPhaseOutcome.FINISH_OK ;
              }
              catch (final XAException xae)
              {
                  if (jtaLogger.logger.isTraceEnabled()) {
                      jtaLogger.logger.trace("XAOnePhaseResource.commit(" + xid + ") " + xae.getMessage());
                  }
      
                  switch (xae.errorCode)
                  {
                  case XAException.XA_HEURHAZ:
                  case XAException.XA_HEURMIX:
                      return TwoPhaseOutcome.HEURISTIC_HAZARD;
                  case XAException.XA_HEURCOM:
                      doForget = true;
                      return TwoPhaseOutcome.FINISH_OK;
                  case XAException.XA_HEURRB:
                      doForget = true;
                      return TwoPhaseOutcome.ONE_PHASE_ERROR;
                  case XAException.XA_RBROLLBACK:
                  case XAException.XA_RBCOMMFAIL:
                  case XAException.XA_RBDEADLOCK:
                  case XAException.XA_RBINTEGRITY:
                  case XAException.XA_RBOTHER:
                  case XAException.XA_RBPROTO:
                  case XAException.XA_RBTIMEOUT:
                  case XAException.XA_RBTRANSIENT:
                  case XAException.XAER_RMERR:
                      return TwoPhaseOutcome.ONE_PHASE_ERROR;
                  case XAException.XAER_NOTA:
                      return TwoPhaseOutcome.HEURISTIC_HAZARD; // something committed or rolled back without asking us!
                  case XAException.XAER_INVAL: // resource manager failed, did it rollback?
                      return TwoPhaseOutcome.HEURISTIC_HAZARD;
                  case XAException.XA_RETRY:  // XA does not allow this to be thrown for 1PC!
                  case XAException.XAER_PROTO:
                      return TwoPhaseOutcome.ONE_PHASE_ERROR; // assume rollback
                  case XAException.XAER_RMFAIL:
                  default:
                      return TwoPhaseOutcome.FINISH_ERROR;  // recovery should retry
                  }
              }......
      

      ...

      The XAException that is caught here contains the original error that caused the transaction to rollback. All this information is completely lost when commit returns only an error key. Even logging the error message does not help because the interesting exception is wrapped inside the XAException.

      Any idea how I can get the original cause for the exception in my business logic? Btw. why does commit not simply throw another exception that wraps the original cause? Thanks in advance. Sebastian