@Override
  public TransactionHandle acquire(long id) throws TransactionLifecycleException {
    TransactionMarker marker = registry.get(id);

    if (null == marker) {
      throw new InvalidTransactionId();
    }

    SuspendedTransaction transaction = marker.getSuspendedTransaction();
    if (registry.replace(id, marker, marker.getActiveTransaction())) {
      return transaction.transactionHandle;
    } else {
      throw new InvalidConcurrentTransactionAccess();
    }
  }
  @Override
  public TransactionHandle terminate(long id) throws TransactionLifecycleException {
    TransactionMarker marker = registry.get(id);
    if (null == marker) {
      throw new InvalidTransactionId();
    } else {
      TransactionTerminationHandle handle = marker.getActiveTransaction().getTerminationHandle();
      handle.terminate();

      try {
        return acquire(id);
      } catch (InvalidConcurrentTransactionAccess exception) {
        // We could not acquire the transaction. Let the other request clean up.
        return null;
      }
    }
  }
  @Override
  public long release(long id, TransactionHandle transactionHandle) {
    TransactionMarker marker = registry.get(id);

    if (null == marker) {
      throw new IllegalStateException("Trying to suspend unregistered transaction");
    }

    if (marker.isSuspended()) {
      throw new IllegalStateException("Trying to suspend transaction that was already suspended");
    }

    SuspendedTransaction suspendedTx =
        new SuspendedTransaction(marker.getActiveTransaction(), transactionHandle);
    if (!registry.replace(id, marker, suspendedTx)) {
      throw new IllegalStateException(
          "Trying to suspend transaction that has been concurrently suspended");
    }
    return computeNewExpiryTime(suspendedTx.getLastActiveTimestamp());
  }