public void commit()

in geode-core/src/main/java/org/apache/geode/internal/jta/TransactionManagerImpl.java [217:392]


  public void commit() throws HeuristicRollbackException, RollbackException,
      HeuristicMixedException, SystemException {
    if (!isActive) {
      throw new SystemException(
          "TransactionManager invalid");
    }
    int cozOfException = -1;
    Transaction transactionImpl = getTransaction();
    if (transactionImpl == null) {
      String exception =
          "Transaction is null, cannot commit a null transaction";
      LogWriter writer = TransactionUtils.getLogWriter();
      if (VERBOSE) {
        writer.fine(exception);
      }
      throw new IllegalStateException(exception);
    }
    GlobalTransaction gtx = getGlobalTransaction(transactionImpl);
    if (gtx == null) {
      String exception =
          "Global Transaction is null, cannot commit a null global transaction";
      LogWriter writer = TransactionUtils.getLogWriter();
      if (VERBOSE) {
        writer.fine(exception);
      }
      throw new SystemException(exception);
    }
    boolean isCommit = false;
    // ensure only one thread can commit. Use a synchronized block
    // Asif
    int status = -1;
    if (((status = gtx.getStatus()) == Status.STATUS_ACTIVE)
        || status == Status.STATUS_MARKED_ROLLBACK) {
      synchronized (gtx) {
        if ((status = gtx.getStatus()) == Status.STATUS_ACTIVE) {
          gtx.setStatus(Status.STATUS_COMMITTING);
          isCommit = true;
        } else if (status == Status.STATUS_MARKED_ROLLBACK) {
          gtx.setStatus(Status.STATUS_ROLLING_BACK);
          cozOfException = MARKED_ROLLBACK;
        } else {
          String exception =
              String.format("transaction not active, cannot be committed. Transaction Status= %s",
                  status);
          LogWriter writer = TransactionUtils.getLogWriter();
          if (VERBOSE) {
            writer.fine(exception);
          }
          throw new IllegalStateException(exception);
        }
      }
    } else {
      String exception =
          "transaction is not active and cannot be committed";
      LogWriter writer = TransactionUtils.getLogWriter();
      if (VERBOSE) {
        writer.fine(exception);
      }
      throw new IllegalStateException(exception);
    }
    // Only one thread can call commit (the first thread to do reach the block
    // above).
    // Before commiting the notifications to be done before the done are called
    // the global transaction is called and then the after completion
    // notifications
    // are taken care of. The transactions associated to the global
    // transactions are
    // removed from the map and also the tread to transaction.
    //
    // Asif : Store the thrown Exception in case of commit .
    // Reuse it for thrwing later.
    // Asif TODO:Verify if it is a good practise
    boolean isClean = false;
    Exception e = null;
    try {
      ((TransactionImpl) transactionImpl).notifyBeforeCompletion();
      isClean = true;
    } catch (Exception ge) {
      // Asif : Just mark the Tranxn to setRollbackOnly to ensure Rollback
      setRollbackOnly();
      cozOfException = EXCEPTION_IN_NOTIFY_BEFORE_COMPLETION;
      e = ge;
    }
    // TODO:Asif In case the status of transaction is marked as
    // ROLLING_BACK , then we don't have to take a synch block
    // As once the status is marked for ROLLING_BACK , setRollnbackonly
    // will be harmless
    if (isCommit) {
      synchronized (gtx) {
        if ((status = gtx.getStatus()) == Status.STATUS_COMMITTING) {
          // Asif: Catch any exception encountered during commit
          // and appropriately mark the exception code
          try {
            gtx.commit();
          } catch (RollbackException rbe) {
            e = rbe;
            cozOfException = COMMIT_FAILED_SO_ROLLEDBAK;
          } catch (SystemException se) {
            e = se;
            cozOfException = COMMIT_FAILED_ROLLBAK_ALSO_FAILED;
          }
        } else if (status == Status.STATUS_ROLLING_BACK) {
          try {
            gtx.rollback();
            if (isClean) {
              cozOfException = MARKED_ROLLBACK;
            }
          } catch (SystemException se) {
            e = se;
            cozOfException = ROLLBAK_FAILED;
          }
        }
      }
    } else {
      try {
        gtx.rollback();
      } catch (SystemException se) {
        e = se;
        cozOfException = ROLLBAK_FAILED;
      }
    }
    try {
      ((TransactionImpl) transactionImpl).notifyAfterCompletion(status = gtx.getStatus());
    } catch (Exception ge) {
      LogWriter writer = TransactionUtils.getLogWriter();
      if (writer.infoEnabled()) {
        writer.info(
            String.format("Exception in notify after completion due to %s",
                ge.getMessage()),
            ge);
      }
    }
    Thread thread = Thread.currentThread();
    transactionMap.remove(thread);
    gtxSet.remove(gtx);
    if (status != Status.STATUS_COMMITTED) {
      switch (cozOfException) {
        case EXCEPTION_IN_NOTIFY_BEFORE_COMPLETION: {
          String exception =
              "Transaction rolled back because of Exception in notifyBeforeCompletion processing";
          LogWriter writer = TransactionUtils.getLogWriter();
          if (VERBOSE) {
            writer.fine(exception, e);
          }
          RollbackException re = new RollbackException(exception);
          re.initCause(e);
          throw re;
        }
        case MARKED_ROLLBACK: {
          String exception =
              "Transaction rolled back because a user marked it for Rollback";
          LogWriter writer = TransactionUtils.getLogWriter();
          if (VERBOSE) {
            writer.fine(exception, e);
          }
          throw new RollbackException(exception);
        }
        case COMMIT_FAILED_SO_ROLLEDBAK: {
          LogWriter writer = TransactionUtils.getLogWriter();
          if (VERBOSE) {
            writer.fine(e);
          }
          throw (RollbackException) e;
        }
        case COMMIT_FAILED_ROLLBAK_ALSO_FAILED:
        case ROLLBAK_FAILED: {
          LogWriter writer = TransactionUtils.getLogWriter();
          if (VERBOSE) {
            writer.fine(e);
          }
          throw (SystemException) e;
        }
      }
    }
    gtx.setStatus(Status.STATUS_NO_TRANSACTION);
  }