public void begin(final JmsTransactionId txId, final AsyncResult request) throws Exception {
    if (current != null) {
      throw new IOException("Begin called while a TX is still Active.");
    }

    final AsyncResult declareCompletion =
        new AsyncResult() {

          @Override
          public void onSuccess() {
            current = txId;
            request.onSuccess();
          }

          @Override
          public void onFailure(Throwable result) {
            current = null;
            request.onFailure(result);
          }

          @Override
          public boolean isComplete() {
            return current != null;
          }
        };

    if (coordinator == null || coordinator.isClosed()) {
      AmqpTransactionCoordinatorBuilder builder =
          new AmqpTransactionCoordinatorBuilder(this, session.getResourceInfo());
      builder.buildResource(
          new AsyncResult() {

            @Override
            public void onSuccess() {
              try {
                coordinator.declare(txId, declareCompletion);
              } catch (Exception e) {
                request.onFailure(e);
              }
            }

            @Override
            public void onFailure(Throwable result) {
              request.onFailure(result);
            }

            @Override
            public boolean isComplete() {
              return request.isComplete();
            }
          });
    } else {
      coordinator.declare(txId, declareCompletion);
    }
  }
  public void rollback(JmsTransactionInfo transactionInfo, final AsyncResult request)
      throws Exception {
    if (!transactionInfo.getId().equals(current)) {
      if (!transactionInfo.isInDoubt() && current == null) {
        throw new IllegalStateException("Rollback called with no active Transaction.");
      } else if (!transactionInfo.isInDoubt() && current != null) {
        throw new IllegalStateException(
            "Attempt to rollback a transaction other than the current one");
      } else {
        request.onSuccess();
        return;
      }
    }

    preRollback();

    LOG.trace("TX Context[{}] rolling back current TX[[]]", this, current);
    coordinator.discharge(
        current,
        new AsyncResult() {

          @Override
          public void onSuccess() {
            current = null;
            postRollback();
            request.onSuccess();
          }

          @Override
          public void onFailure(Throwable result) {
            current = null;
            postRollback();
            request.onFailure(result);
          }

          @Override
          public boolean isComplete() {
            return current == null;
          }
        },
        false);
  }
  public void commit(JmsTransactionInfo transactionInfo, final AsyncResult request)
      throws Exception {
    if (!transactionInfo.getId().equals(current)) {
      if (!transactionInfo.isInDoubt() && current == null) {
        throw new IllegalStateException("Commit called with no active Transaction.");
      } else if (!transactionInfo.isInDoubt() && current != null) {
        throw new IllegalStateException(
            "Attempt to Commit a transaction other than the current one");
      } else {
        throw new TransactionRolledBackException("Transaction in doubt and cannot be committed.");
      }
    }

    preCommit();

    LOG.trace("TX Context[{}] committing current TX[[]]", this, current);
    coordinator.discharge(
        current,
        new AsyncResult() {

          @Override
          public void onSuccess() {
            current = null;
            postCommit();
            request.onSuccess();
          }

          @Override
          public void onFailure(Throwable result) {
            current = null;
            postCommit();
            request.onFailure(result);
          }

          @Override
          public boolean isComplete() {
            return current == null;
          }
        },
        true);
  }
 public boolean isTransactionFailed() {
   return coordinator == null ? false : coordinator.isClosed();
 }