@Override
  public void rollback(Xid xid) throws XAException {
    if (logger.logDebug()) {
      debug("rolling back xid = " + xid);
    }

    // We don't explicitly check precondition 1.

    try {
      if (currentXid != null && xid.equals(currentXid)) {
        state = STATE_IDLE;
        currentXid = null;
        conn.rollback();
        conn.setAutoCommit(localAutoCommitMode);
      } else {
        String s = RecoveredXid.xidToString(xid);
        conn.setAutoCommit(true);
        conn.rollbackPreparedTransaction(s);
      }
    } catch (CloudSpannerSQLException ex) {
      if (ex.getCode().equals(Code.NOT_FOUND)) {
        throw new CloudSpannerXAException(CloudSpannerXAException.ERROR_ROLLBACK_PREPARED, ex,
            XAException.XAER_NOTA);
      }
      throw new CloudSpannerXAException(CloudSpannerXAException.ERROR_ROLLBACK_PREPARED, ex,
          XAException.XAER_RMERR);
    } catch (SQLException ex) {
      throw new CloudSpannerXAException(CloudSpannerXAException.ERROR_ROLLBACK_PREPARED, ex,
          Code.UNKNOWN, XAException.XAER_RMERR);
    }
  }
@ Override public void rollback ( Xid xid ) throws XAException { if ( logger . logDebug ( ) ) { debug ( "rolling back xid = " + xid ) ; } try { if ( currentXid != null && xid . equals ( currentXid ) ) { state = STATE_IDLE ; currentXid = null ; conn . rollback ( ) ; conn . setAutoCommit ( localAutoCommitMode ) ; } else { String s = RecoveredXid . xidToString ( xid ) ; conn . setAutoCommit ( true ) ; conn . rollbackPreparedTransaction ( s ) ; } } catch ( CloudSpannerSQLException ex ) { if ( ex . getCode ( ) . equals ( Code . NOT_FOUND ) ) { throw new CloudSpannerXAException ( CloudSpannerXAException . ERROR_ROLLBACK_PREPARED , ex , XAException . XAER_NOTA ) ; } throw new CloudSpannerXAException ( CloudSpannerXAException . ERROR_ROLLBACK_PREPARED , ex , XAException . XAER_RMERR ) ; } catch ( SQLException ex ) { throw new CloudSpannerXAException ( CloudSpannerXAException . ERROR_ROLLBACK_PREPARED , ex , Code . UNKNOWN , XAException . XAER_RMERR ) ; } }
Preconditions: 1. xid is known to the RM or it's in prepared state

Implementation deficiency preconditions: 1. xid must be associated with this connection if it's
not in prepared state.

Postconditions: 1. Transaction is rolled back and disassociated from connection