docs: @Override
    public void start(Xid xid, int flags) throws XAException {
      if (LOGGER.isLoggable(Level.FINEST)) {
        debug("starting transaction xid = " + xid);
      }
  
      // Check preconditions
      if (flags != XAResource.TMNOFLAGS && flags != XAResource.TMRESUME
          && flags != XAResource.TMJOIN) {
        throw new PGXAException(GT.tr("Invalid flags {0}", flags), XAException.XAER_INVAL);
      }
  
      if (xid == null) {
        throw new PGXAException(GT.tr("xid must not be null"), XAException.XAER_INVAL);
      }
  
      if (state == State.ACTIVE) {
        throw new PGXAException(GT.tr("Connection is busy with another transaction"),
            XAException.XAER_PROTO);
      }
  
      // We can't check precondition 4 easily, so we don't. Duplicate xid will be catched in prepare
      // phase.
  
      // Check implementation deficiency preconditions
      if (flags == TMRESUME) {
        throw new PGXAException(GT.tr("suspend/resume not implemented"), XAException.XAER_RMERR);
      }
  
      // It's ok to join an ended transaction. WebLogic does that.
      if (flags == TMJOIN) {
        if (state != State.ENDED) {
          throw new PGXAException(
              GT.tr(
                  "Invalid protocol state requested. Attempted transaction interleaving is not supported. xid={0}, currentXid={1}, state={2}, flags={3}",
                  xid, currentXid, state, flags), XAException.XAER_RMERR);
        }
  
        if (!xid.equals(currentXid)) {
          throw new PGXAException(
              GT.tr(
                  "Invalid protocol state requested. Attempted transaction interleaving is not supported. xid={0}, currentXid={1}, state={2}, flags={3}",
                  xid, currentXid, state, flags), XAException.XAER_RMERR);
        }
      } else if (state == State.ENDED) {
        throw new PGXAException(GT.tr("Invalid protocol state requested. Attempted transaction interleaving is not supported. xid={0}, currentXid={1}, state={2}, flags={3}", xid, currentXid, state, flags),
            XAException.XAER_RMERR);
      }
  
      // Only need save localAutoCommitMode for NOFLAGS, TMRESUME and TMJOIN already saved old
      // localAutoCommitMode.
      if (flags == TMNOFLAGS) {
        try {
          localAutoCommitMode = conn.getAutoCommit();
          conn.setAutoCommit(false);
        } catch (SQLException ex) {
          throw new PGXAException(GT.tr("Error disabling autocommit"), ex, XAException.XAER_RMERR);
        }
      }
  
      // Preconditions are met, Associate connection with the transaction
      state = State.ACTIVE;
      currentXid = xid;
      preparedXid = null;
      committedOrRolledBack = false;
    }