/** * 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()); } }
public void run() { transactionContext.execute( new TransactionContextCallback<Object>() { public Object doInTransaction() throws CompassException { delegate.run(); return null; } }); }
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); } }
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; } } } }