/** Vote using phase-1 of the 2-phase commit. */
  public int prepare(Xid xid) throws XAException {
    if (_endFlags != -1) {
      int endFlags = _endFlags;
      _endFlags = -1;

      if (_isXATransaction) endResource(xid, endFlags);
    }

    if (_isXATransaction) {
      try {
        if (log.isLoggable(Level.FINER)) log.finer("prepare-XA: " + xid + " " + _xaResource);

        int result = _xaResource.prepare(xid);

        if (result == XA_RDONLY) {
          if (_xaResource != null) _isXATransaction = true;

          clearXid();
        }

        return result;
      } catch (XAException e) {
        if (log.isLoggable(Level.FINER))
          log.finer("failed prepare-XA: " + xid + " " + _xaResource + " " + e);

        throw e;
      }
    } else return XA_OK;
  }
  /** rollback the resource */
  public void rollback(Xid xid) throws XAException {
    try {
      int endFlags = _endFlags;
      _endFlags = -1;

      if (endFlags != -1 && _isXATransaction) {
        boolean isValid = false;

        try {
          endResource(xid, endFlags);
          isValid = true;
        } finally {
          if (!isValid) _xaResource.rollback(xid);
        }
      }

      if (log.isLoggable(Level.FINER)) log.finer("connection pool rollback XA: " + this);

      if (_isXATransaction) _xaResource.rollback(xid);
      else if (_localTransaction != null) {
        try {
          _isLocalTransaction = false;
          _localTransaction.rollback();
        } catch (ResourceException e) {
          throw new XAExceptionWrapper(e);
        }
      }
    } finally {
      if (_xaResource != null) _isXATransaction = true;

      clearXid();
    }
  }
 /** forget about the transaction */
 public void forget(Xid xid) throws XAException {
   try {
     if (_isXATransaction) _xaResource.forget(xid);
   } finally {
     clearXid();
   }
 }
  /** commit the resource */
  public void commit(Xid xid, boolean onePhase) throws XAException {
    boolean logFiner = log.isLoggable(Level.FINER);

    try {
      int endFlags = _endFlags;
      _endFlags = -1;

      if (endFlags != -1 && _isXATransaction) {
        boolean isValid = false;

        try {
          endResource(xid, endFlags);
          isValid = true;
        } finally {
          if (!isValid) _xaResource.rollback(xid);
        }
      }

      if (_isXATransaction) {
        if (logFiner) {
          log.finer("commit-XA" + (onePhase ? "-1p: " : ": ") + xid + " " + _xaResource);
        }

        try {
          _xaResource.commit(xid, onePhase);
        } catch (XAException e) {
          if (logFiner) log.finer("commit-XA failed: " + _xaResource + " " + e);

          throw e;
        }
      } else if (_localTransaction != null) {
        if (logFiner) log.finer("commit-local: " + _localTransaction);

        try {
          _localTransaction.commit();
        } catch (ResourceException e) {
          if (logFiner) log.finer("commit failed: " + _localTransaction + " " + e);

          throw new XAExceptionWrapper(e);
        } finally {
          _isLocalTransaction = false;
        }
      } else {
        if (logFiner) log.finer("commit for resource with no XA support: " + this);
      }
    } finally {
      if (_xaResource != null) _isXATransaction = true;

      clearXid();
    }
  }
  /** Restores the delegation for the entire chain. */
  private void clearXid() {
    _xid = null;

    UserPoolItem shareHead = _shareHead;
    _shareHead = null;

    ManagedPoolItem xaPtr = _xaNext;
    _xaHead = null;
    _xaNext = null;

    UserPoolItem assignedUserItem = null;
    for (UserPoolItem ptr = shareHead; ptr != null; ptr = ptr.getShareNext()) {
      if (ptr.getOwnPoolItem() == this) {
        assignedUserItem = ptr;
        break;
      }
    }

    for (UserPoolItem ptr = shareHead; ptr != null; ptr = ptr.getShareNext()) {
      if (assignedUserItem == null && ptr.getOwnPoolItem() == null) {
        ptr.associatePoolItem(this);
        assignedUserItem = ptr;
      }

      try {
        ptr.reassociatePoolItem();
      } catch (Throwable e) {
        log.log(Level.WARNING, e.toString(), e);
      }
    }

    while (xaPtr != null) {
      ManagedPoolItem next = xaPtr._xaNext;
      xaPtr._xaNext = null;
      xaPtr._xaHead = null;

      xaPtr.clearXid();

      xaPtr = next;
    }

    if (assignedUserItem != null) {
      // _shareHead = assignedUserItem;
      // _shareHead.setShareNext(null);
    } else if (_hasConnectionError) {
      destroy();
    } else {
      toIdle();
    }
  }