/**
   * Do the commit. This is the 2nd phase of the 2-phase protocol.
   *
   * @param transactionState
   * @throws CommitUnsuccessfulException
   */
  void doCommit(final TransactionState transactionState) throws CommitUnsuccessfulException {
    try {
      LOG.trace("Commiting [" + transactionState.getTransactionId() + "]");

      transactionLogger.setStatusForTransaction(
          transactionState.getTransactionId(), TransactionLogger.TransactionStatus.COMMITTED);

      for (HRegionLocation location : transactionState.getParticipatingRegions()) {
        if (transactionState.getRegionsToIngore().contains(location)) {
          continue;
        }
        TransactionalRegionInterface transactionalRegionServer =
            (TransactionalRegionInterface)
                connection.getHRegionConnection(location.getServerAddress());
        transactionalRegionServer.commit(
            location.getRegionInfo().getRegionName(), transactionState.getTransactionId());
      }
    } catch (Exception e) {
      LOG.info(
          "Commit of transaction [" + transactionState.getTransactionId() + "] was unsucsessful",
          e);
      // This happens on a NSRE that is triggered by a split
      try {
        abort(transactionState);
      } catch (Exception abortException) {
        LOG.warn("Exeption durring abort", abortException);
      }
      throw new CommitUnsuccessfulException(e);
    }
    transactionLogger.forgetTransaction(transactionState.getTransactionId());
  }
  /**
   * Abort a s transaction.
   *
   * @param transactionState
   * @throws IOException
   */
  public void abort(final TransactionState transactionState) throws IOException {
    transactionLogger.setStatusForTransaction(
        transactionState.getTransactionId(), TransactionLogger.TransactionStatus.ABORTED);

    for (HRegionLocation location : transactionState.getParticipatingRegions()) {
      if (transactionState.getRegionsToIngore().contains(location)) {
        continue;
      }
      try {
        TransactionalRegionInterface transactionalRegionServer =
            (TransactionalRegionInterface)
                connection.getHRegionConnection(location.getServerAddress());

        transactionalRegionServer.abortTransaction(
            location.getRegionInfo().getRegionName(), transactionState.getTransactionId());
      } catch (UnknownTransactionException e) {
        LOG.info(
            "Got unknown transaciton exception durring abort. Transaction: ["
                + transactionState.getTransactionId()
                + "], region: ["
                + location.getRegionInfo().getRegionNameAsString()
                + "]. Ignoring.");
      } catch (NotServingRegionException e) {
        LOG.info(
            "Got NSRE durring abort. Transaction: ["
                + transactionState.getTransactionId()
                + "], region: ["
                + location.getRegionInfo().getRegionNameAsString()
                + "]. Ignoring.");
      }
    }
    transactionLogger.forgetTransaction(transactionState.getTransactionId());
  }
  /**
   * Try and commit a transaction. This does both phases of the 2-phase protocol: prepare and
   * commit.
   *
   * @param transactionState
   * @throws IOException
   * @throws CommitUnsuccessfulException
   */
  public void tryCommit(final TransactionState transactionState)
      throws CommitUnsuccessfulException, IOException {
    long startTime = EnvironmentEdgeManager.currentTimeMillis();
    LOG.trace("atempting to commit trasaction: " + transactionState.toString());
    int status = prepareCommit(transactionState);

    if (status == TransactionalRegionInterface.COMMIT_OK) {
      doCommit(transactionState);
    } else if (status == TransactionalRegionInterface.COMMIT_OK_READ_ONLY) {
      transactionLogger.forgetTransaction(transactionState.getTransactionId());
    } else if (status == TransactionalRegionInterface.COMMIT_UNSUCESSFUL) {
      // We have already aborted at this point
      throw new CommitUnsuccessfulException();
    }
    LOG.trace(
        "Committed transaction ["
            + transactionState.getTransactionId()
            + "] in ["
            + ((EnvironmentEdgeManager.currentTimeMillis() - startTime))
            + "]ms");
  }
 /**
  * Called to start a transaction.
  *
  * @return new transaction state
  */
 public TransactionState beginTransaction() {
   long transactionId = transactionLogger.createNewTransactionLog();
   LOG.debug("Begining transaction " + transactionId);
   return new TransactionState(transactionId);
 }