code: private void commitPrepared(Xid xid) throws XAException {
      try {
        // Check preconditions. The connection mustn't be used for another
        // other XA or local transaction, or the COMMIT PREPARED command
        // would mess it up.
        if (state != STATE_IDLE || conn.getTransaction().hasBufferedMutations()) {
          throw new CloudSpannerXAException(CloudSpannerXAException.TWO_PHASE_IDLE,
              Code.FAILED_PRECONDITION, XAException.XAER_RMERR);
        }
  
        String s = RecoveredXid.xidToString(xid);
  
        localAutoCommitMode = conn.getAutoCommit();
        conn.setAutoCommit(true);
        try {
          conn.commitPreparedTransaction(s);
        } finally {
          conn.setAutoCommit(localAutoCommitMode);
        }
      } catch (CloudSpannerSQLException ex) {
        throw new CloudSpannerXAException(CloudSpannerXAException.ERROR_COMMIT_PREPARED, ex,
            XAException.XAER_RMERR);
      } catch (SQLException ex) {
        throw new CloudSpannerXAException(CloudSpannerXAException.ERROR_COMMIT_PREPARED, ex,
            Code.UNKNOWN, XAException.XAER_RMERR);
      }
    }
docs: Preconditions: 1. xid must be in prepared state in the server
  
  Implementation deficiency preconditions: 1. Connection must be in idle state
  
  Postconditions: 1. Transaction is committed