/**
   * Determine whether a test-managed transaction is currently <em>active</em>.
   *
   * @return {@code true} if a test-managed transaction is currently active
   * @see #start()
   * @see #end()
   */
  public static boolean isActive() {
    TransactionContext transactionContext = TransactionContextHolder.getCurrentTransactionContext();
    if (transactionContext != null) {
      TransactionStatus transactionStatus = transactionContext.getTransactionStatus();
      return (transactionStatus != null) && (!transactionStatus.isCompleted());
    }

    // else
    return false;
  }
 @Override
 public void abortTransaction(ITransactionContext txnCtx, DatasetId datasetId, int PKHashVal)
     throws ACIDException {
   if (txnCtx.getTxnState() != ITransactionManager.ABORTED) {
     txnCtx.setTxnState(ITransactionManager.ABORTED);
   }
   try {
     if (txnCtx.isWriteTxn()) {
       LogRecord logRecord = ((TransactionContext) txnCtx).getLogRecord();
       logRecord.formJobTerminateLogRecord(txnCtx, false);
       txnSubsystem.getLogManager().log(logRecord);
       txnSubsystem.getRecoveryManager().rollbackTransaction(txnCtx);
     }
   } catch (Exception ae) {
     String msg = "Could not complete rollback! System is in an inconsistent state";
     if (LOGGER.isLoggable(Level.SEVERE)) {
       LOGGER.severe(msg);
     }
     ae.printStackTrace();
     throw new ACIDException(msg, ae);
   } finally {
     ((TransactionContext) txnCtx).cleanupForAbort();
     txnSubsystem.getLockManager().releaseLocks(txnCtx);
     transactionContextRepository.remove(txnCtx.getJobId());
   }
 }
Пример #3
0
 public void run() {
   transactionContext.execute(
       new TransactionContextCallback<Object>() {
         public Object doInTransaction() throws CompassException {
           delegate.run();
           return null;
         }
       });
 }
Пример #4
0
  private boolean commitInternal(
      LockID lockID, ClientTransaction currentTransaction, boolean isWaitContext) {
    Assert.assertNotNull("transaction", currentTransaction);

    try {
      disableTransactionLogging();

      // If the current transactionContext is READ_ONLY, there is no need to commit.
      TransactionContext tc = peekContext(lockID);
      if (tc.getType().equals(TxnType.READ_ONLY)) {
        txMonitor.committedReadTransaction();
        return false;
      }

      boolean hasPendingCreateObjects = objectManager.hasPendingCreateObjects();
      if (hasPendingCreateObjects) {
        objectManager.addPendingCreateObjectsToTransaction();
      }

      currentTransaction.setAlreadyCommitted();
      if (currentTransaction.hasChangesOrNotifies() || hasPendingCreateObjects) {
        if (txMonitor.isEnabled()) {
          currentTransaction.updateMBean(txMonitor);
        }
        remoteTxManager.commit(currentTransaction);
      }
      return true;
    } finally {
      enableTransactionLogging();

      // always try to unlock even if we are throwing an exception
      // if (!isWaitContext && !currentTransaction.isNull()) {
      // lockManager.unlock(currentTransaction.getLockID());
      // }
      if (!isWaitContext && !currentTransaction.isNull()) {
        if (lockID != null && !lockID.isNull()) {
          lockManager.unlock(lockID);
        } else {
          throw new AssertionError("Trying to unlock with lockID = null!");
        }
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  public TransactionContext start() throws Exception {
    TransactionContext txnContext = holder.get();
    if (txnContext != null) {
      throw new TransactionException("A transaction was found in the ThreadLocal.");
    }

    txnContext = new DefaultTransactionContext();
    holder.set(txnContext);

    // Check the thread locals for known resources
    Connection connection = ConnectionContext.get();
    if (connection != null) {
      txnContext.add(new JDBCTransactionalResource(connection));
    }

    EntityManager em = EntityManagerContext.get();
    if (em != null) {
      txnContext.add(new JPATransactionalResource(em));
    }

    return txnContext;
  }
 /**
  * Start a new transaction for the supplied {@link TestContext test context}.
  *
  * <p>Only call this method if {@link #endTransaction} has been called or if no transaction has
  * been previously started.
  *
  * @param testContext the current test context
  * @throws TransactionException if starting the transaction fails
  * @throws Exception if an error occurs while retrieving the transaction manager
  */
 private void startNewTransaction(TestContext testContext, TransactionContext txContext)
     throws Exception {
   txContext.startTransaction();
   ++this.transactionsStarted;
   if (logger.isInfoEnabled()) {
     logger.info(
         "Began transaction ("
             + this.transactionsStarted
             + "): transaction manager ["
             + txContext.transactionManager
             + "]; rollback ["
             + isRollback(testContext)
             + "]");
   }
 }
 /**
  * Immediately force a <em>commit</em> or <em>rollback</em> of the transaction for the supplied
  * {@link TestContext test context}, according to the commit and rollback flags.
  *
  * @param testContext the current test context
  * @throws Exception if an error occurs while retrieving the transaction manager
  */
 private void endTransaction(TestContext testContext, TransactionContext txContext)
     throws Exception {
   boolean rollback = isRollback(testContext);
   if (logger.isTraceEnabled()) {
     logger.trace(
         "Ending transaction for test context "
             + testContext
             + "; transaction manager ["
             + txContext.transactionStatus
             + "]; rollback ["
             + rollback
             + "]");
   }
   txContext.endTransaction(rollback);
   if (logger.isInfoEnabled()) {
     logger.info(
         (rollback ? "Rolled back" : "Committed")
             + " transaction after test execution for test context "
             + testContext);
   }
 }
Пример #8
0
  private void updateTransactionStatus() throws SQLException {
    // if there is a is an active transaction context, assure the transaction context hasn't changed
    if (transactionContext != null) {
      if (transactionContext.isActive()) {
        if (transactionContext != transactionRegistry.getActiveTransactionContext()) {
          throw new SQLException(
              "Connection can not be used while enlisted in another transaction");
        }
        return;
      } else {
        // transaction should have been cleared up by TransactionContextListener, but in
        // rare cases another lister could have registered which uses the connection before
        // our listener is called.  In that rare case, trigger the transaction complete call now
        transactionComplete();
      }
    }

    // the existing transaction context ended (or we didn't have one), get the active transaction
    // context
    transactionContext = transactionRegistry.getActiveTransactionContext();

    // if there is an active transaction context and it already has a shared connection, use it
    if (transactionContext != null && transactionContext.getSharedConnection() != null) {
      // A connection for the connection factory has already been enrolled
      // in the transaction, replace our delegate with the enrolled connection

      // return current connection to the pool
      Connection connection = getDelegateInternal();
      setDelegate(null);
      if (connection != null) {
        try {
          pool.returnObject(connection);
        } catch (Exception ignored) {
          // whatever... try to invalidate the connection
          try {
            pool.invalidateObject(connection);
          } catch (Exception ignore) {
            // no big deal
          }
        }
      }

      // add a listener to the transaction context
      transactionContext.addTransactionContextListener(new CompletionListener());

      // set our delegate to the shared connection
      setDelegate(transactionContext.getSharedConnection());

      // remember that we are using a shared connection so it can be cleared after the
      // transaction completes
      isSharedConnection = true;
    } else {
      // if our delegate is null, create one
      if (getDelegateInternal() == null) {
        try {
          // borrow a new connection from the pool
          Connection connection = (Connection) pool.borrowObject();
          setDelegate(connection);
        } catch (Exception e) {
          throw (SQLException)
              new SQLException("Unable to acquire a new connection from the pool").initCause(e);
        }
      }

      // if we have a transaction, out delegate becomes the shared delegate
      if (transactionContext != null) {
        // add a listener to the transaction context
        transactionContext.addTransactionContextListener(new CompletionListener());

        // register our connection as the shared connection
        try {
          transactionContext.setSharedConnection(getDelegateInternal());
        } catch (SQLException e) {
          // transaction is hosed
          transactionContext = null;
          throw e;
        }
      }
    }
  }