コード例 #1
0
  private void rollbackSuspended(Predicate<TransactionMarker> predicate) {
    Set<Long> candidateTransactionIdsToRollback = new HashSet<Long>();

    for (Map.Entry<Long, TransactionMarker> entry : registry.entrySet()) {
      TransactionMarker marker = entry.getValue();
      if (marker.isSuspended() && predicate.accept(marker)) {
        candidateTransactionIdsToRollback.add(entry.getKey());
      }
    }

    for (long id : candidateTransactionIdsToRollback) {
      TransactionHandle handle;
      try {
        handle = acquire(id);
      } catch (TransactionLifecycleException invalidTransactionId) {
        // Allow this - someone snatched the transaction from under our feet,
        continue;
      }
      try {
        handle.forceRollback();
        log.info(format("Transaction with id %d has been automatically rolled back.", id));
      } catch (Throwable e) {
        log.error(format("Transaction with id %d failed to roll back.", id), e);
      } finally {
        forget(id);
      }
    }
  }
コード例 #2
0
  @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();
    }
  }
コード例 #3
0
  @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;
      }
    }
  }
コード例 #4
0
  @Override
  public void forget(long id) {
    TransactionMarker marker = registry.get(id);

    if (null == marker) {
      throw new IllegalStateException("Could not finish unregistered transaction");
    }

    if (marker.isSuspended()) {
      throw new IllegalStateException("Cannot finish suspended registered transaction");
    }

    if (!registry.remove(id, marker)) {
      throw new IllegalStateException(
          "Trying to finish transaction that has been concurrently finished or suspended");
    }
  }
コード例 #5
0
  @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());
  }