@Override
  public void end(Xid xid, int flags) throws XAException {
    if (logger.logDebug()) {
      debug("ending transaction xid = " + xid);
    }

    // Check preconditions

    if (flags != XAResource.TMSUSPEND && flags != XAResource.TMFAIL
        && flags != XAResource.TMSUCCESS) {
      throw new CloudSpannerXAException(CloudSpannerXAException.INVALID_FLAGS,
          Code.INVALID_ARGUMENT, XAException.XAER_INVAL);
    }

    if (xid == null) {
      throw new CloudSpannerXAException(CloudSpannerXAException.XID_NOT_NULL, Code.INVALID_ARGUMENT,
          XAException.XAER_INVAL);
    }

    if (state != STATE_ACTIVE || !currentXid.equals(xid)) {
      throw new CloudSpannerXAException(CloudSpannerXAException.END_WITHOUT_START,
          Code.FAILED_PRECONDITION, XAException.XAER_PROTO);
    }

    // Check implementation deficiency preconditions
    if (flags == XAResource.TMSUSPEND) {
      throw new CloudSpannerXAException(CloudSpannerXAException.SUSPEND_NOT_IMPLEMENTED,
          Code.UNIMPLEMENTED, XAException.XAER_RMERR);
    }

    // We ignore TMFAIL. It's just a hint to the RM. We could roll back
    // immediately
    // if TMFAIL was given.

    // All clear. We don't have any real work to do.
    state = STATE_ENDED;
  }
@ Override public void end ( Xid xid , int flags ) throws XAException { if ( logger . logDebug ( ) ) { debug ( "ending transaction xid = " + xid ) ; } if ( flags != XAResource . TMSUSPEND && flags != XAResource . TMFAIL && flags != XAResource . TMSUCCESS ) { throw new CloudSpannerXAException ( CloudSpannerXAException . INVALID_FLAGS , Code . INVALID_ARGUMENT , XAException . XAER_INVAL ) ; } if ( xid == null ) { throw new CloudSpannerXAException ( CloudSpannerXAException . XID_NOT_NULL , Code . INVALID_ARGUMENT , XAException . XAER_INVAL ) ; } if ( state != STATE_ACTIVE || ! currentXid . equals ( xid ) ) { throw new CloudSpannerXAException ( CloudSpannerXAException . END_WITHOUT_START , Code . FAILED_PRECONDITION , XAException . XAER_PROTO ) ; } if ( flags == XAResource . TMSUSPEND ) { throw new CloudSpannerXAException ( CloudSpannerXAException . SUSPEND_NOT_IMPLEMENTED , Code . UNIMPLEMENTED , XAException . XAER_RMERR ) ; } state = STATE_ENDED ; }
Preconditions: 1. Flags is one of TMSUCCESS, TMFAIL, TMSUSPEND 2. xid != null 3. Connection is
associated with transaction xid

Implementation deficiency preconditions: 1. Flags is not TMSUSPEND

Postconditions: 1. connection is disassociated from the transaction.

@see XAResource#end(Xid, int)