/** * Begin a transaction within a context if required. The context will define a transaction type * and if the type requires a transaction one will be begun. * * @param transaction A <code>Transaction</code>. * @param context A <code>TransactionContext</code>. * @throws NamingException * @throws NotSupportedException */ private void beginXA(final Transaction transaction, final TransactionContext context) { XA_LOGGER.logVariable("transaction", transaction); XA_LOGGER.logVariable("context", context); /* when the transaction context is set, nothing is done * * when the transaction context is null, no transaction boundary is * currently set, so we need to check whether nor not to begin the * transaction based upon the type */ if (isSetXAContext()) { switch (context.getType()) { case REQUIRED: XA_LOGGER.logInfo("{0}Join {1} with {2}.", "\t\t", context, getXAContext()); break; case REQUIRES_NEW: LOGGER.logFatal("New transaction required-{0}", context); XA_LOGGER.logFatal("New transaction required-{0}", context); Assert.assertUnreachable("New transaction required-{0}", context); break; case NEVER: XA_LOGGER.logInfo("{0}No transaction participation-{1}.", "\t\t", context); break; case SUPPORTED: break; default: LOGGER.logFatal("Unknown transaction type."); XA_LOGGER.logFatal("Unknown transaction type."); Assert.assertUnreachable("Unknown transaction type."); } } else { switch (context.getType()) { case REQUIRES_NEW: case REQUIRED: setXAContext(context); transaction.begin(); XA_LOGGER.logInfo("Begin transaction-{0}.", context); break; case NEVER: XA_LOGGER.logInfo("{0}No transaction participation-{1}.", "\t\t", context); break; case SUPPORTED: break; default: LOGGER.logFatal("Unknown transaction type."); XA_LOGGER.logFatal("Unknown transaction type."); Assert.assertUnreachable("Unknown transaction type."); } } }
/** * Complete a transaction. If the transaction belongs to the given transaction context a * rollback/commit will be attempted. * * @param transaction A <code>Transaction</code>. * @param transactionContext A <code>TransactionContext</code>. * @throws HeuristicMixedException * @throws HeuristicRollbackException * @throws RollbackException */ private void completeXA(final Transaction transaction, final TransactionContext context) { if (isSetXAContext() && getXAContext().equals(context)) { unsetXAContext(); if (transaction.isRollbackOnly()) { XA_LOGGER.logInfo("Rolling transaction-{0}.", context); transaction.rollback(); } else { XA_LOGGER.logInfo("Committing transaction-{0}.", context); transaction.commit(); } } else { switch (context.getType()) { case REQUIRES_NEW: case REQUIRED: case SUPPORTED: break; case NEVER: XA_LOGGER.logInfo("No transaction participation-{0}.", context); break; default: LOGGER.logFatal("Unknown transaction type."); XA_LOGGER.logFatal("Unknown transaction type."); Assert.assertUnreachable("Unknown transaction type."); } } }
/** * Rollback a transaction. If the transaction belongs to the context; a rollback will be * attempted. If it does not; depending on the context type; the transaction's rollback only flag * will be set. * * @param transaction A <code>Transaction</code>. * @param transactionContext A <code>TransactionContext</code>. */ private void rollbackXA(final Transaction transaction, final TransactionContext context) { switch (context.getType()) { case REQUIRES_NEW: case REQUIRED: XA_LOGGER.logInfo("Set rollback only-{0}.", context); transaction.setRollbackOnly(); break; case NEVER: XA_LOGGER.logInfo("No transaction participation-{0}.", context); break; case SUPPORTED: if (transaction.isActive()) { XA_LOGGER.logInfo("Set rollback only-{0}.", context); transaction.setRollbackOnly(); } else { XA_LOGGER.logTrace("Transaction for {0} is not active.", context); } break; default: LOGGER.logFatal("Unknown transaction type."); XA_LOGGER.logFatal("Unknown transaction type."); Assert.assertUnreachable("Unknown transaction type."); } }