jsr343-experts@jms-spec.java.net

[jsr343-experts] Re: (JMS_SPEC-45) Clarify and improve Connection.createSession

From: Reza Rahman <reza_rahman_at_lycos.com>
Date: Tue, 09 Aug 2011 10:18:43 -0400

Nigel,

This looks like a very good change. If we feel something needs to be
fixed in the EJB spec, do let me know if there is something I can do to
help.

Cheers,
Reza


On 8/9/2011 6:35 AM, Nigel Deakin wrote:
> I have logged the following JIRA issue:
> http://java.net/jira/browse/JMS_SPEC-45
>
> This is quite a long description and it may be easier to read the
> formatted version in the JIRA issue rather than the text version
> below. In any case, I would appreciate your comments.
>
> Nigel
>
>
> In the JMS 1.1 specification, the following method on a
> javax.jms.Connection is used to create a javax.jms.Session:
>
> Session createSession(boolean transacted, int acknowledgeMode) throws
> JMSException
>
> where transacted may be set to true or false and
> acknowledgeMode may be set to Session.AUTO_ACKNOWLEDGE,
> Session.CLIENT_ACKNOWLEDGE, and Session.DUPS_OK_ACKNOWLEDGE
>
> (There are similar methods on javax.jms.QueueConnection and
> javax.jms.TopicConnection: this whole issue applies to all three.)
>
> This is a rather confusing method for several reasons:
>
> * It uses two arguments to define a single aspect of the session
> * In a Java EE transaction, both arguments are ignored anyway
> * In a Java EE unspecified transaction context, the meaning of the
> arguments is undefined and unclear
>
> It uses two arguments to define the same thing
> ----------------------------------------------
>
> This method uses two arguments to define what is in practice a single
> aspect of the session with four possibilities: if transacted is set to
> false then the session is non-transacted and the acknowledgeMode
> argument defines which of three kinds of acknowledgement are used when
> receiving messages. If transacted is set to true then the
> acknowledgeMode argument is ignored.
>
> This is inconsistent with the method Session.getAcknowledgeMode()
> which returns one of four values: Session.AUTO_ACKNOWLEDGE,
> Session.CLIENT_ACKNOWLEDGE, or Session.DUPS_OK_ACKNOWLEDGE if the
> session is not transacted and Session.SESSION_TRANSACTED if the
> session is transacted.
>
> This also leads to code which is potentially misleading, since if
> transacted is false the user still has to set acknowledgeMode to some
> value even if it is ignored, which leads to code such as
> Session session =
> connection.createSession(true,Session.AUTO_ACKNOWLEDGE);
>
> Some developers like to use
>
> Session session =
> connection.createSession(true,Session.SESSION_TRANSACTED);
>
> though this is still misleading since since if transacted was set to
> true then the second argument is ignored anyway, and if transacted is
> false then setting acknowledgeMode to Session.SESSION_TRANSACTED would
> be an error.
>
> In a Java EE transaction, both arguments are ignored anyway
> -----------------------------------------------------------
>
> In a Java EE transaction none of the four options listed above are
> permitted. Instead, both arguments to connection.createSession are
> ignored and a global transaction is used.
>
> The EJB 3.1 Specification, section 13.3.5 "use of JMS APIs in
> Transactions" states that, in a container-managed or bean-managed
> transaction,
> {quote}
> Because the container manages the transactional enlistment of JMS
> sessions on behalf of a bean, the parameters of the
> createSession(boolean transacted, int acknowledgeMode) method
> createQueueSession... are ignored.
> {quote}
>
> This also applies to web applications. The Java EE platform spec,
> Section EE.6.7 "Java Message Service (JMS) 1.1 Requirements" specifies
> that
>
> "The behavior of a JMS provider should be the same in both the EJB
> container and the web container." It continues "The EJB specification
> describes restrictions on the use of JMS in an EJB container, as well
> as the interaction of JMS with transactions in an EJB container.
> Applications running in the web container should follow the same
> restrictions."
>
> Instead, the receiving and sending of messages must be part of the
> container-managed or bean-managed transaction, and the transaction
> will be committed or rolled back in the way that container-managed or
> bean-managed transactions are committed or rolled back.
>
> * Container-managed transactions are either committed when the
> appropriate business method completes or are rolled back using
> EJBContext.setRollbackOnly.
>
> * Bean-managed transactions are either committed using
> UserTransaction.commit or rolled back using UserTransaction.rollback.
>
> How explicit is the EJB specification about all this? In addition to
> specifying that in a transactional context the arguments to
> Connection.createSession are ignored, it also states the following:
>
> * Section 13.3.5 states that "within a transaction" the bean should
> not use the acknowledge method. This therefore covers both
> container-managed and bean-managed transactions.
>
> * Section 13.3.3 states that in the case of _bean-managed_
> transactions, the bean must not invoke the commit or rollback methods
> on the javax.jms.Session interface.
>
> * Section 13.3.4 states that in the case of _container-managed_
> transactions, the bean must not "use any resource-managed specific
> transaction management methods that would interfere with the
> container's demarcation of transaction boundaries" and again must not
> invoke the commit or rollback methods on the javax.jms.Session interface.
>
> * Section 13.1.1 states that in the case of _bean-managed_
> transactions, "all resource manager accesses between the
> UserTransaction.begin and UserTransaction.commit calls are part of a
> transaction", thereby apparently ruling out the use of non-transacted
> sessions using auto-acknowledgement and dups-ok-acknowledgement as
> well as those using client-acknowledgement.
>
> * Section 13.1.1 also states in a _container-managed_ transaction the
> transaction demarcation depends on the transaction attributes of the
> bean method. It doesn't explicitly state that all resource manager
> accesses should be part of this transaction, but this is implied.
>
> In a Java EE unspecified transaction context, the meaning of the
> arguments undefined and unclear
> ------------------------------------------------------------------------------------------------
>
>
> The previous section only relates to the use of the JMS API "in
> transactions". It does not cover how the JMS API should behave when
> there is no current container-managed or bean-managed transaction.
> That is, when there is an unspecified transaction context.
>
> The EJB 3.1 Specification, section 13.6.5 "Handling of Methods that
> run with an unspecified transaction context" defines an "unspecified
> transaction context" as covering "the cases in which the EJB
> architecture does not fully define the transaction semantics of an
> enterprise bean method execution".
>
> Section 13.6.5 goes on to give a list of examples of when an
> "unspecified transaction context" may arise. All the cases given are
> for container-managed transactions, leaving an ambiguity about what an
> "unspecified transaction context" means when using bean-managed
> transactions. An obvious interpretation is that that if a bean is
> configured to use bean-managed transactions, then business methods or
> onMessage() code executed before a call to userTransaction.begin(), or
> after a call to UserTransaction.commit or UserTransaction.rollback, is
> executed in an unspecified transaction context, as is any code
> executed in the four bean lifecycle callback methods listed in 13.6.5
> (PostConstruct,PreDestroy, PostActivate, or PrePassivate). However
> this is not explicitly stated in the EJB spec.
>
> So, what does the EJB spec say should happen in an "unspecified
> transaction context"?
>
> Section 13.6.5 is written with all resource managers (not just JMS) in
> mind, and states that
>
> "The EJB specification does not prescribe how the container should
> manage the execution of a method with an unspecified transaction
> context—the transaction semantics are left to the container
> implementation."
>
> It goes on to give some options, which include treating "each call...
> to a resource manager as a single transaction", merging multiple calls
> into a single transaction, or accessing the resource manager "without
> a transaction context".
>
> Now in the case of JMS the application has a way to give the container
> a hint as to what behaviour they desire: the arguments to
> {[createSession. So it would seem reasonable to follow these.
>
> However the EJB 3.1 specification, section 13.3.5 does explicitly
> state 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.
>
> It is curious that although Session.acknowledge is prohibited in a
> unspecified transaction context, Session.commit is not, even though
> both perform message acknowledgement. If the former is invalid, then
> the latter must be as well.
>
> This means that within an unspecified transaction context:
>
> * a non-transacted session using client acknowledgement is explicitly
> prohibited
> * a (local) transacted session is implicitly prohibited
> * a non-transacted session is permitted, with both
> client-acknowledgement and dups-ok-acknowledgement (which is an
> optimised version of auto-acknowledgement) allowed.
>
> h4.Summary
>
> So in Connection.createSession (and QueueConnection.createQueueSession
> and TopicConnection.createTopicSession we have a method which offers
> different options depending on the context in which it is used:
>
> * In a Java EE transaction there are no options: the session is part
> of a transaction managed by the container and the application has no
> choice on the matter.
>
> * In a Java EE unspecified transaction context there are two options:
> ** non-transacted session with auto-acknowledgement
> ** non-transacted session with dups-ok-acknowledgement
>
> * In a Java SE environment there are four options:
> ** non-transacted session with auto-acknowledgement
> ** non-transacted session with dups-ok-acknowledgement
> ** non-transacted session with client-acknowledgement
> ** transacted session
>
> So, in the light of all this, what are the problems?
>
> * the special behaviour of this method in a Java EE transaction is not
> mentioned anywhere in the JMS specification or in the javadocs, which
> means that users are surprised when they discover that the arguments
> to createSession are ignored. Fortunately, however, the required
> behaviour is clearly defined in the EJB specification.
>
> * the special behaviour in a Java EE unspecified transaction context
> is also not mentioned anywhere in the JMS specification or in the
> javadocs. Unfortunately, the required behaviour is not explicitly
> described in the EJB specification but has to be pieced together from
> various different sections, as in the analysis above. This needs to be
> confirmed and stated explicitly.
>
> * the actual API for createSession, with its two arguments, not only
> does not reflect the four options available in the normal Java SE
> case, it does not reflect the zero options available in the Java EE
> transaction case or the two options available in the Java EE
> unspecified transaction context case. However when compared the the
> two preceding issues this is perhaps not such a major issue.
>
> Proposals
> ---------
>
> It is proposed that
>
> * The JMS specification and javadocs be updated to describe how
> createSession behaves in a Java EE applicaiton, both in a transaction
> and in an unspecified transaction context. The former case will be a
> restatement of the existing EJB spec, the latter case will be intended
> to remove any ambiguities in the EJB spec along the lines of the
> analysis above.
>
> * A new method be provided in a javax.jms.Connection
>
> Session createSession(int sessionMode) throws JMSException
>
> where sessionMode may be set to Session.AUTO_ACKNOWLEDGE,
> Session.CLIENT_ACKNOWLEDGE, Session.DUPS_OK_ACKNOWLEDGE or
> Session.AUTO_TRANSACTED
>
> * The existing createSession will remain with a note that it may be
> removed from a future release of the API.
>
>
>
>
>
> -----
> No virus found in this message.
> Checked by AVG - www.avg.com
> Version: 10.0.1392 / Virus Database: 1520/3822 - Release Date: 08/08/11
>
>