@Override
  public void start(Xid xid, int flags) throws XAException {

    synchronized (cpoXaStateMap) {
      // see if we are already associated with a global transaction
      if (cpoXaStateMap.getXaResourceMap().get(this) != null)
        throw CpoXaError.createXAException(CpoXaError.XAER_PROTO, "Start can not be called on an associated XID");

      // see if we are not in the middle of doing something on the local transaction
      if (isLocalResourceBusy())
        throw CpoXaError.createXAException(CpoXaError.XAER_OUTSIDE, "Local Transaction is busy");

      CpoXaState<T> cpoXaState = cpoXaStateMap.getXidStateMap().get(xid);

      switch (flags) {
        case TMNOFLAGS: // Starting a new transaction ID
          // if it is already in use then throw a dupe id error
          if (cpoXaState != null)
            throw CpoXaError.createXAException(CpoXaError.XAER_DUPID, "Duplicate XID");

          cpoXaState = new CpoXaState<>(xid, createNewResource(), CpoXaState.XA_ASSOCIATED, this, true);
          cpoXaStateMap.getXidStateMap().put(xid, cpoXaState);
          cpoXaStateMap.getXaResourceMap().put(this, xid);
          break;

        case TMJOIN:
          if (cpoXaState == null)
            throw CpoXaError.createXAException(CpoXaError.XAER_NOTA, "Unknown XID");

          if (cpoXaState.getAssociation()==CpoXaState.XA_UNASSOCIATED) {
            cpoXaState.setAssociation(CpoXaState.XA_ASSOCIATED);
            cpoXaState.setAssignedResourceManager(this);
            cpoXaStateMap.getXaResourceMap().put(this, xid);
          } else {
            throw CpoXaError.createXAException(CpoXaError.XAER_PROTO, "TMJOIN can only be used with an unassociated XID");
          }
          break;

        case TMRESUME:
          if (cpoXaState == null)
            throw CpoXaError.createXAException(CpoXaError.XAER_NOTA, "Unknown XID");

          // you can only resume a suspended transaction
          if (cpoXaState.getAssociation() == CpoXaState.XA_SUSPENDED) {
            cpoXaState.setAssociation(CpoXaState.XA_ASSOCIATED);
            cpoXaState.setAssignedResourceManager(this);
            cpoXaStateMap.getXaResourceMap().put(this, xid);
          } else {
            throw CpoXaError.createXAException(CpoXaError.XAER_PROTO, "TMRESUME can only be used with a suspended XID");
          }
          break;

        default: // invalid arguments
          throw CpoXaError.createXAException(CpoXaError.XAER_INVAL, "Invalid start() flag");
      }
    }
  }
@ Override public void start ( Xid xid , int flags ) throws XAException { synchronized ( cpoXaStateMap ) { if ( cpoXaStateMap . getXaResourceMap ( ) . get ( this ) != null ) throw CpoXaError . createXAException ( CpoXaError . XAER_PROTO , "Start can not be called on an associated XID" ) ; if ( isLocalResourceBusy ( ) ) throw CpoXaError . createXAException ( CpoXaError . XAER_OUTSIDE , "Local Transaction is busy" ) ; CpoXaState < T > cpoXaState = cpoXaStateMap . getXidStateMap ( ) . get ( xid ) ; switch ( flags ) { case TMNOFLAGS : if ( cpoXaState != null ) throw CpoXaError . createXAException ( CpoXaError . XAER_DUPID , "Duplicate XID" ) ; cpoXaState = new CpoXaState < > ( xid , createNewResource ( ) , CpoXaState . XA_ASSOCIATED , this , true ) ; cpoXaStateMap . getXidStateMap ( ) . put ( xid , cpoXaState ) ; cpoXaStateMap . getXaResourceMap ( ) . put ( this , xid ) ; break ; case TMJOIN : if ( cpoXaState == null ) throw CpoXaError . createXAException ( CpoXaError . XAER_NOTA , "Unknown XID" ) ; if ( cpoXaState . getAssociation ( ) == CpoXaState . XA_UNASSOCIATED ) { cpoXaState . setAssociation ( CpoXaState . XA_ASSOCIATED ) ; cpoXaState . setAssignedResourceManager ( this ) ; cpoXaStateMap . getXaResourceMap ( ) . put ( this , xid ) ; } else { throw CpoXaError . createXAException ( CpoXaError . XAER_PROTO , "TMJOIN can only be used with an unassociated XID" ) ; } break ; case TMRESUME : if ( cpoXaState == null ) throw CpoXaError . createXAException ( CpoXaError . XAER_NOTA , "Unknown XID" ) ; if ( cpoXaState . getAssociation ( ) == CpoXaState . XA_SUSPENDED ) { cpoXaState . setAssociation ( CpoXaState . XA_ASSOCIATED ) ; cpoXaState . setAssignedResourceManager ( this ) ; cpoXaStateMap . getXaResourceMap ( ) . put ( this , xid ) ; } else { throw CpoXaError . createXAException ( CpoXaError . XAER_PROTO , "TMRESUME can only be used with a suspended XID" ) ; } break ; default : throw CpoXaError . createXAException ( CpoXaError . XAER_INVAL , "Invalid start() flag" ) ; } } }
Starts work on behalf of a transaction branch specified in xid. If TMJOIN is specified, the start applies to joining a transaction previously seen by the
resource manager. If TMRESUME is specified, the start applies to resuming a suspended transaction specified in the parameter xid. If neither TMJOIN nor TMRESUME
is specified and the transaction specified by xid has previously been seen by the resource manager, the resource manager throws the XAException exception with
XAER_DUPID error code.

@param xid   - A global transaction identifier to be associated with the resource.
@param flags - One of TMNOFLAGS, TMJOIN, or TMRESUME.
@throws XAException - An error has occurred. Possible exceptions are XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_DUPID, XAER_OUTSIDE, XAER_NOTA, XAER_INVAL, or XAER_PROTO.