[JMS_SPEC-131] Allow client-acknowledgement and local transactions to be used in the Java EE web and EJB container Created: 18/Jun/13 Updated: 18/Jun/13
|Remaining Estimate:||Not Specified|
|Time Spent:||Not Specified|
|Original Estimate:||Not Specified|
The JMS 2.0 specification, section 12.3 "Behaviour of JMS sessions in the Java EE web or EJB container" states that if a Session or JMSContext is created when there is no active JTA transaction in progress, then the Session or JMSContext that is created will be non-transacted and any messages received will be automatically acknowledged.
The specification states that the use of local transactions or client acknowledgement is not permitted. A session parameter may be used to specify whether the acknowledgement mode should be AUTO_ACKNOWLEDGE or DUPS_OK_ACKNOWLEDGE, but any other values will be ignored.
Issue: When there is no application server transaction (or if the Session or JMSContext has opted out of the JTA transaction if allowed by JMS_SPEC-130), should client-acknowledgement or local transactions be permitted?
If so, we would need to define an appropriate API by which the application specifies this. We can't use the existing parameters to createSession and createContext for this purpose since these must be ignored in accordance with the EJB 3.1 specification).
|Comment by Nigel Deakin [ 18/Jun/13 ]|
Historical background behind the current restrictions
The current restrictions precede JMS 2.0 and were defined in EJB 3.1 (and possible earlier versions). In EJB 3.1, section 13.3.5 "Use of JMS APIs in transactions" states that “because the container manages the transactional enlistment of JMS sessions on behalf of a bean, the parameters of the createSession... methods are ignored."
The same section states that "The Bean Provider should not use the JMS acknowledge method either within a transaction or within an unspecified transaction context. Message acknowledgment in an unspecified transaction context is handled by the container."
JMS 2.0 took the view that the reference to "message acknowledgement" being "handled by the container" forbade use of both the Session.acknowledge() and the Session.commit() methods, since they both perform message acknowledgement. However EJB 3.1 did not explicitly mention the Session.commit() method.
Rationale behind the current restrictions
In an email exchange with one of the original authors of the JMS specification it was stated that the reason for not allowing client-acknowledgement (and presumably local transactions) was that it should be possible to change the transactional behaviour of an application my modifying the deployment descriptor without the need to change the code.
However this really only applies for container-managed transactions. A bean-managed transaction is, by definition, defined in the code.
Additional restriction when using an injected JMSContext
JMS 2.0 explicitly forbids the use of client acknowledgement or local transactions in an injected JMSContext object. This restriction is additional to the restrictions on the use of Session (and now JMSContext) objects defined in the EJB specification, and is imposed because an injected JMSContext needs to be "stateless" to avoid users getting confused by the same JMSContext object being used in multiple components within the same scope.
Imagine a user creates two EJBs (or other Java EE components such as a servlet or CDI bean) and injects a JMSContext into each, using the same annotations. If the two EJBs are used within the same transaction, or, if there is no transaction, within the same request, then the two injected JMSContext fields will (in accordance with expected CDI behaviour) refer to the same object. This means that calling a method such as acknowledge() or commit() on one JMSContext field would have an effect on the other JMSContext field. It was decided that this was potentially confusing and a possible cause of errors, especially if the two EJBs were developed by different people. To avoid this confusion it was decided to simply disallow the use of client-acknowledgement or local transactions on an injected JMSContext.
Since client-acknowledgement and local transactions were not allowed in a EJB or web application anyway, restricting their use on an injected JMSContext did not introduce any additional limitations. However this means that even if the specification was relaxed in the future to allow client-acknowledgement and local transactions in Java EE applications it would still be necessary to restrict their use when the JMSContext was injected unless the goal of making a JMSContext stateless was abandoned.