use of javax.transaction.Transaction in project tomee by apache.
the class TransactionalTest method requiresNew.
@Test
public void requiresNew() {
final AtomicReference<Transaction> tx2 = new AtomicReference<>();
final Transaction tx1 = bean.defaultTx(new Runnable() {
@Override
public void run() {
tx2.set(bean.newTx(new Runnable() {
@Override
public void run() {
// no-op
}
}));
}
});
assertNotSame(tx1, tx2.get());
}
use of javax.transaction.Transaction in project Payara by payara.
the class SafeProperties method doAfterBegin.
// Implementation of Container method.
// Called from UserTransactionImpl after the EJB started a Tx,
// for TX_BEAN_MANAGED EJBs only.
public final void doAfterBegin(ComponentInvocation ci) {
EjbInvocation inv = (EjbInvocation) ci;
try {
// Associate the context with tx so that on subsequent
// invocations with the same tx, we can do the appropriate
// tx.resume etc.
EJBContextImpl sc = (EJBContextImpl) inv.context;
Transaction tx = transactionManager.getTransaction();
if (!isSingleton) {
sc.setTransaction(tx);
}
// Register Synchronization with TM so that we can
// dissociate the context from tx in afterCompletion
ejbContainerUtilImpl.getContainerSync(tx).addBean(sc);
enlistExtendedEntityManagers(sc);
// Dont call container.afterBegin() because
// TX_BEAN_MANAGED EntityBeans are not allowed,
// and SessionSync calls on TX_BEAN_MANAGED SessionBeans
// are not allowed.
} catch (SystemException ex) {
throw new EJBException(ex);
} catch (RollbackException ex) {
throw new EJBException(ex);
} catch (IllegalStateException ex) {
throw new EJBException(ex);
}
}
use of javax.transaction.Transaction in project Payara by payara.
the class EJBContainerTransactionManager method preInvokeTx.
/**
* Handle transaction requirements, if any, before invoking bean method
*/
final void preInvokeTx(EjbInvocation inv) throws Exception {
// Get existing Tx status: this tells us if the client
// started a transaction which was propagated on this invocation.
Integer preInvokeTxStatus = inv.getPreInvokeTxStatus();
int status = (preInvokeTxStatus != null) ? preInvokeTxStatus.intValue() : transactionManager.getStatus();
// For EntityBeans, ejbCreate/ejbRemove/ejbFind must be called with a Tx so no special work needed.
if (container.suspendTransaction(inv)) {
if (status != Status.STATUS_NO_TRANSACTION) {
// client request is associated with a Tx
try {
inv.clientTx = transactionManager.suspend();
} catch (SystemException ex) {
throw new EJBException(ex);
}
}
return;
}
// isNullTx is true if the client sent a null tx context
// (i.e. a tx context with a null Coordinator objref)
// or if this server's tx interop mode flag is false.
// Follow the tables in EJB2.0 sections 19.6.2.2.1 and 19.6.2.2.2.
boolean isNullTx = false;
if (inv.isRemote) {
isNullTx = transactionManager.isNullTransaction();
}
int txAttr = container.getTxAttr(inv);
EJBContextImpl context = (EJBContextImpl) inv.context;
// Note: in the code below, inv.clientTx is set ONLY if the
// client's Tx is actually suspended.
// get the Tx associated with the EJB from previous invocation,
// if any.
Transaction prevTx = context.getTransaction();
switch(txAttr) {
case Container.TX_BEAN_MANAGED:
// Note: only MDBs and SessionBeans can be TX_BEAN_MANAGED
if (status != Status.STATUS_NO_TRANSACTION) {
// client request associated with a Tx, always suspend
inv.clientTx = transactionManager.suspend();
}
if (container.isStatefulSession && prevTx != null && prevTx.getStatus() != Status.STATUS_NO_TRANSACTION) {
// Note: if prevTx != null , then it means
// afterCompletion was not called yet for the
// previous transaction on the EJB.
// The EJB was previously associated with a Tx which was
// begun by the EJB itself in a previous invocation.
// This is only possible for stateful SessionBeans
// not for StatelessSession or Entity.
transactionManager.resume(prevTx);
// This allows the TM to enlist resources
// used by the EJB with the transaction
transactionManager.enlistComponentResources();
}
break;
case Container.TX_NOT_SUPPORTED:
if (status != Status.STATUS_NO_TRANSACTION) {
inv.clientTx = transactionManager.suspend();
}
container.checkUnfinishedTx(prevTx, inv);
container.preInvokeNoTx(inv);
break;
case Container.TX_MANDATORY:
if (isNullTx || status == Status.STATUS_NO_TRANSACTION) {
throw new TransactionRequiredLocalException();
}
useClientTx(prevTx, inv);
break;
case Container.TX_REQUIRED:
if (isNullTx) {
throw new TransactionRequiredLocalException();
}
if (status == Status.STATUS_NO_TRANSACTION) {
inv.clientTx = null;
startNewTx(prevTx, inv);
} else {
// There is a client Tx
inv.clientTx = transactionManager.getTransaction();
useClientTx(prevTx, inv);
}
break;
case Container.TX_REQUIRES_NEW:
if (status != Status.STATUS_NO_TRANSACTION) {
inv.clientTx = transactionManager.suspend();
}
startNewTx(prevTx, inv);
break;
case Container.TX_SUPPORTS:
if (isNullTx) {
throw new TransactionRequiredLocalException();
}
if (status != Status.STATUS_NO_TRANSACTION) {
useClientTx(prevTx, inv);
} else {
// we need to invoke the EJB with no Tx.
container.checkUnfinishedTx(prevTx, inv);
container.preInvokeNoTx(inv);
}
break;
case Container.TX_NEVER:
if (isNullTx || status != Status.STATUS_NO_TRANSACTION) {
throw new EJBException("EJB cannot be invoked in global transaction");
} else {
// we need to invoke the EJB with no Tx.
container.checkUnfinishedTx(prevTx, inv);
container.preInvokeNoTx(inv);
}
break;
default:
throw new EJBException("Bad transaction attribute");
}
}
use of javax.transaction.Transaction in project Payara by payara.
the class EJBContainerTransactionManager method startNewTx.
/**
* Start a CMT transaction, enlist resources, and call afterBegin, which is a
* no-op in those containers that do not need this callback
*/
private void startNewTx(Transaction prevTx, EjbInvocation inv) throws Exception {
container.checkUnfinishedTx(prevTx, inv);
if (cmtTimeoutInSeconds > 0) {
transactionManager.begin(cmtTimeoutInSeconds);
} else {
transactionManager.begin();
}
EJBContextImpl context = (EJBContextImpl) inv.context;
Transaction tx = transactionManager.getTransaction();
if (!container.isSingleton) {
context.setTransaction(tx);
}
// This allows the TM to enlist resources used by the EJB
// with the transaction
transactionManager.enlistComponentResources();
// register synchronization for methods other than finders/home methods
if (!inv.invocationInfo.isHomeFinder) {
// Register for Synchronization notification
ejbContainerUtilImpl.getContainerSync(tx).addBean(context);
}
// Call afterBegin/ejbLoad. If ejbLoad throws exceptions,
// the completeNewTx machinery called by postInvokeTx
// will rollback the tx. Since we have already registered
// a Synchronization object with the TM, the afterCompletion
// will get called.
container.afterBegin(context);
}
use of javax.transaction.Transaction in project Payara by payara.
the class EJBContainerTransactionManager method useClientTx.
/**
* Use caller transaction to execute a bean method
*/
protected void useClientTx(Transaction prevTx, EjbInvocation inv) {
Transaction clientTx;
int status = -1;
int prevStatus = -1;
try {
// Note: inv.clientTx will not be set at this point.
clientTx = transactionManager.getTransaction();
// clientTx cant be null
status = clientTx.getStatus();
if (prevTx != null) {
prevStatus = prevTx.getStatus();
}
} catch (Exception ex) {
try {
transactionManager.setRollbackOnly();
} catch (Exception e) {
// FIXME: Use LogStrings.properties
_logger.log(Level.FINEST, "", e);
}
throw new TransactionRolledbackLocalException("", ex);
}
// to invoke the EJB, so throw an exception back to client.
if (status == Status.STATUS_MARKED_ROLLBACK || status == Status.STATUS_ROLLEDBACK || status == Status.STATUS_ROLLING_BACK) {
throw new TransactionRolledbackLocalException("Client's transaction aborted");
}
container.validateEMForClientTx(inv, (JavaEETransaction) clientTx);
if (prevTx == null || prevStatus == Status.STATUS_NO_TRANSACTION) {
// First time the bean is running in this new client Tx
EJBContextImpl context = (EJBContextImpl) inv.context;
// Must change this for singleton
if (!container.isSingleton) {
context.setTransaction(clientTx);
}
try {
transactionManager.enlistComponentResources();
if (!container.isStatelessSession && !container.isMessageDriven && !container.isSingleton) {
// Register sync for methods other than finders/home methods
if (!inv.invocationInfo.isHomeFinder) {
ejbContainerUtilImpl.getContainerSync(clientTx).addBean(context);
}
container.afterBegin(context);
}
} catch (Exception ex) {
try {
transactionManager.setRollbackOnly();
} catch (Exception e) {
// FIXME: Use LogStrings.properties
_logger.log(Level.FINEST, "", e);
}
throw new TransactionRolledbackLocalException("", ex);
}
} else {
// Bean already has a transaction associated with it.
if (!prevTx.equals(clientTx)) {
// EntityBeans will get a different context for every Tx.
if (container.isSession) {
// Row 2 in Table E
throw new IllegalStateException("EJB is already associated with an incomplete transaction");
}
} else {
// with the transaction
try {
transactionManager.enlistComponentResources();
} catch (Exception ex) {
try {
transactionManager.setRollbackOnly();
} catch (Exception e) {
// FIXME: Use LogStrings.properties
_logger.log(Level.FINEST, "", e);
}
throw new TransactionRolledbackLocalException("", ex);
}
}
}
}
Aggregations