How to control an EJB Transaction from the Client in EAP 7.1 +
Environment
- Red Hat JBoss Enterprise Application Platform (EAP)
- 7.3
- 7.2
- 7.1
Issue
- Is there a way to avoid enlisting the ResourceImpl/EJBClientContext on the client side when using a remote interface for an EJB which does anyway not participate in the client transaction ?
- Is it possible to prevent transaction propagation in EJB invocation from an EAP instance to another?
Resolution
From EAP 7.1 onwards you can use @org.jboss.ejb.client.annotation.ClientTransaction annotation to require transaction propagation from an EJB Client (i.e. fail if the client has no transaction) or to prevent it (i.e. propagate no transaction even if the client has one active).
You can control the policy of the ClientTransaction annotation through the Constants of org.jboss.ejb.client.annotation.ClientTransactionPolicy interface which are the following ones:
SUPPORTS(DEFAULT) : Invoke without a transaction if there is no client-side transaction context; propagate the client-side transaction context if it is present. (This is the default policy)MANDATORY: Fail with exception when there is no client-side transaction context; propagate the client-side transaction context when it is present.NEVER: Invoke without propagating any transaction context; if a client-side transaction context is present, an exception is thrown.NOT_SUPPORTED: Invoke without propagating any transaction context whether or not a client-side transaction context is present.
If no annotation is present, the default policy is org.jboss.ejb.client.annotation.ClientTransactionPolicy#SUPPORTS, which means that the transaction will be propagated if it is present, but will not fail regardless of whether or not a transaction is present.
The ClientTransactionPolicy does not start transactions, it controls whether the transaction is propagated to the remote EJB and whether it should throw an exception back to the client invoking if it is trying to invoke the remote EJB with or without a tx when the EJB service expects or does not expect a transaction to be propagated.
Example
The annotation applies to each method of the remote interface, or to the whole remote interface as a default value. It affects only calls to that method on that interface.
import org.jboss.ejb.client.annotation.ClientTransaction;
@ClientTransaction(ClientTransactionPolicy.MANDATORY)
public interface RemoteCalculator {
public void callRemoteEjb() { }
}
@Stateless
@Remote(RemoteCalculator.class)
public class CalculatorBean implements RemoteCalculator {
@Override
public void callRemoteEjb() { }
}
The annotation gives a way for the remote interface provider to tell the remote interface consumer that transactions are not needed, or are required, for a method, allowing the client to avoid or require outflow as needed.
Detailed Information
SUPPORTS
Invoke without a transaction if there is no client-side transaction context; propagate the client-side transaction context if it is present. The target may be invoked with or without a client-side transaction context.
This is the overall default policy.
This mode is compatible with the following server-side transaction attribute types:
- TransactionAttributeType.REQUIRED
- TransactionAttributeType.SUPPORTS
- TransactionAttributeType.NOT_SUPPORTED
This mode can also be used with TransactionAttributeType.NEVER and TransactionAttributeType.MANDATORY, however the success of the invocation of such methods will depend on the local transaction state.
Unlike TransactionAttributeType.SUPPORTS, this client-side transaction policy is generally safe to use in all cases, as it still allows the server to decide to create a new transaction according to local policy.
This mode may be used with TransactionAttributeType.REQUIRES_NEW, but such usage may not make sense in most situations because the transaction that is propagated by the client (if any) will always be suspended on the server; in this case, a client-side policy of NOT_SUPPORTED is recommended to avoid the useless propagation of the client-side transaction context.
MANDATORY
Fail with exception when there is no client-side transaction context; propagate the client-side transaction context when it is present. The target is never invoked without a client-side transaction context.
This mode is compatible with the following server-side transaction attribute types:
- TransactionAttributeType.MANDATORY
- TransactionAttributeType.REQUIRED
- TransactionAttributeType.SUPPORTS
This mode is recommended when the server side method uses TransactionAttributeType.MANDATORY.
This mode may be used with TransactionAttributeType.REQUIRES_NEW and TransactionAttributeType.NOT_SUPPORTED, but such usage may not make sense in most situations because the transaction that is required to be propagated by the client will always be suspended on the server; in this case, a client-side policy of TransactionAttributeType.NOT_SUPPORTED is recommended to avoid the useless propagation of the client-side transaction context.
Usage of this mode with the following server-side transaction attribute types will always result in an exception, and is therefore not recommended:
- TransactionAttributeType.NEVER
NOT_SUPPORTED
Invoke without propagating any transaction context whether or not a client-side transaction context is present. The target is always invoked without a client-side transaction context.
This mode is compatible with the following server-side transaction attribute types:
- TransactionAttributeType.REQUIRED
- TransactionAttributeType.REQUIRES_NEW
- TransactionAttributeType.SUPPORTS
- TransactionAttributeType.NOT_SUPPORTED
This mode can also be used with TransactionAttributeType.NEVER, however, in this case the server will never see the client-side transaction, causing the invocation to effectively use the server-side mode TransactionAttributeType.NOT_SUPPORTED in this case, which might result in unexpected behavior.
Usage of this mode with the following server-side transaction attribute types will always result in an exception, and is therefore not recommended:
- TransactionAttributeType.MANDATORY
NEVER
Invoke without propagating any transaction context; if a client-side transaction context is present, an exception is thrown.
This mode is compatible with the following server-side transaction attribute types:
- TransactionAttributeType.REQUIRED
- TransactionAttributeType.REQUIRES_NEW
- TransactionAttributeType.SUPPORTS
- TransactionAttributeType.NOT_SUPPORTED
This mode can also be used with TransactionAttributeType.NEVER, however, in this case the server will never see the client-side transaction, causing the invocation to effectively use the server-side mode TransactionAttributeType.NOT_SUPPORTED in this case, which might result in unexpected behavior.
Usage of this mode with the following server-side transaction attribute types will always result in an exception, and is therefore not recommended:
- TransactionAttributeType.MANDATORY
This content is not included.[1] This content is not included.https://access.redhat.com/webassets/avalon/d/red-hat-jboss-enterprise-application-platform/7.2/javadocs/org/jboss/ejb/client/annotation/ClientTransactionPolicy.html#MANDATORY
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.