jakartaee / messaging

Jakarta Messaging
https://eclipse.org/ee4j/messaging
Other
39 stars 33 forks source link

Resolve some undefined use cases when using Java EE transactions #129

Open glassfishrobot opened 11 years ago

glassfishrobot commented 11 years ago

Case 1

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 an active JTA transaction in progress then the Session or JMSContext will participate in the JTA transaction and will be committed or rolled back when the JTA transaction is committed or rolled back.

However the specification also states that "if a Session or JMSContext is created when there is an active JTA transaction but is subsequently used to send or receive messages when there is no active JTA transaction then the behaviour is undefined".

Issue 1: Can we define what should happen if a Session or JMSContext is created in a JTA transaction but is used to send or receive a message after the JTA transaction has been committed or rolled back?

Here's a simple example:

@Stateless
@LocalBean
@TransactionManagement(value=TransactionManagementType.BEAN)
public class MySessionBean {

   @Resource(lookup="jms/myConnectionFactory") ConnectionFactory connectionFactory;
   @Resource(lookup="jms/myQueue") Queue queue;

   @Inject UserTransaction ut;

   public void doSomething() {

      // start a transaction   
      ut.begin();

      // create JMSContext when there is a transaction      
      JMSContext context = connectionFactory.createContext();

      // commit the transaction
      ut.commit();

      // what happens here?            
      context.createProducer().send(queue,"Hello world");

      context.close();
   }
}

There appear to be three possibilities:

Does it matter if the transaction was rolled back in another thread? (if this is a possible use case).

What happens if we then start a second transaction and use the same JMSContext to send or receive a message (as in the example below)?

@Stateless
@LocalBean
@TransactionManagement(value=TransactionManagementType.BEAN)
public class MySessionBean {

   @Resource(lookup="jms/myConnectionFactory") ConnectionFactory connectionFactory;
   @Resource(lookup="jms/myQueue") Queue queue;

   @Inject UserTransaction ut;

   public void doSomething() {

      // start a transaction   
      ut.begin();

      // create JMSContext when there is a transaction      
      JMSContext context = connectionFactory.createContext();

      // commit the transaction
      ut.commit();

      context.createProducer().send(queue,"Hello world");

      // start a second transaction   
      ut.begin();

      // is this valid?          
      context.createProducer().send(queue,"Hello world");

      // commit the transaction
      ut.commit();

      context.close();
   }
}

Case 2

Conversely, the JMS 2.0 specification 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.

However the specification also states that "if a Session or JMSContext is created when there is no active JTA transaction but subsequently used to send or receive messages when there is an active JTA transaction then the behaviour is undefined."

Issue 2: Can we define what should happen if a Session or JMSContext is created when there is no JTA transaction but is used to send or receive a message when there is an active JTA transaction?

Here's a simple example:

@Stateless
@LocalBean
@TransactionManagement(value=TransactionManagementType.BEAN)
public class MySessionBean {

   @Resource(lookup="jms/myConnectionFactory") ConnectionFactory connectionFactory;
   @Resource(lookup="jms/myQueue") Queue queue;

   @Inject UserTransaction ut;

   public void doSomething() {

      // create JMSContext when there is no transaction      
      JMSContext context = connectionFactory.createContext();

      // now start a transaction
      ut.begin();

      // is this message part of the transaction or not?             
      context.createProducer().send(queue,"Hello world");

      // now commit the transaction
      ut.commit();

      context.close();
   }
}

There appear to be four possibilities:

glassfishrobot commented 6 years ago
glassfishrobot commented 11 years ago

@glassfishrobot Commented Reported by @nigeldeakin

glassfishrobot commented 11 years ago

@glassfishrobot Commented genomeprjct said: Equivalently, what happens in EJB when this occurs?

glassfishrobot commented 11 years ago

@glassfishrobot Commented @nigeldeakin said: John, can you please clarify your question? This issue affects any Java EE component that the UserTransaction API.

N.B. I'm going to log some more issues shortly on related issues.

glassfishrobot commented 11 years ago

@glassfishrobot Commented @nigeldeakin said: Added some code examples to the initial issue description

glassfishrobot commented 11 years ago

@glassfishrobot Commented @nigeldeakin said: Updated summary field.

glassfishrobot commented 11 years ago

@glassfishrobot Commented @nigeldeakin said: The same issues arise for container-managed transactions.

Issue 1 also arises for container-managed transactions as follows: Imagine a stateful session bean with two business methods. The first method has a transactional attribute REQUIRED. This creates a JMSContext or Session and saves it in a field. The second method has a transactional attribute NOT_SUPPORTED. This method uses that JMSContext or Session to send a message. A client calls the first method and then the second.

Issue 2 also arises for container-managed transactions as follows: Imagine a stateful session bean with two business methods. The first method has a transactional attribute NOT_SUPPORTED. This creates a JMSContext or Session and saves it in a field. The second method has a transactional attribute REQUIRED. This method uses that JMSContext or Session to send a message. A client calls the first method and then the second.

glassfishrobot commented 11 years ago

@glassfishrobot Commented Issue-Links: is related to JMS_SPEC-130 JMS_SPEC-131

glassfishrobot commented 7 years ago

@glassfishrobot Commented This issue was imported from java.net JIRA JMS_SPEC-129