/** add session to the end of queue when a transaction starts (depending on isolation mode) */
  public void beginAction(Session session, Statement cs) {

    synchronized (liveTransactionTimestamps) {
      session.actionTimestamp = nextChangeTimestamp();

      if (!session.isTransaction) {
        session.transactionTimestamp = session.actionTimestamp;
        session.isTransaction = true;

        liveTransactionTimestamps.addLast(session.actionTimestamp);
      }
    }

    if (session.hasLocks()) {
      return;
    }

    try {
      writeLock.lock();

      boolean canProceed = beginActionTPL(session, cs);

      if (!canProceed) {
        session.abortTransaction = true;
      }
    } finally {
      writeLock.unlock();
    }
  }
  public void beginTransaction(Session session) {

    synchronized (liveTransactionTimestamps) {
      session.actionTimestamp = nextChangeTimestamp();
      session.transactionTimestamp = session.actionTimestamp;
      session.isTransaction = true;

      liveTransactionTimestamps.addLast(session.transactionTimestamp);
    }
  }
  public void beginTransaction(Session session) {

    writeLock.lock();

    try {
      if (!session.isTransaction) {
        session.actionTimestamp = nextChangeTimestamp();
        session.transactionTimestamp = session.actionTimestamp;
        session.isTransaction = true;

        transactionCount++;

        liveTransactionTimestamps.addLast(session.transactionTimestamp);
      }
    } finally {
      writeLock.unlock();
    }
  }