In this article, you will learn about optionally using JMS Transactions. In JMS, a session you can optionally control the atomic operations. Each of these sessions supports a single series of transactions. Each transaction groups a set of produced or consumed messages into an atomic unit of work. Make sure you have understood Message Acknowledge in JMS.

When the Transaction commits – (jmsContext.commit())

  • Its atomic unit of input is acknowledged.
  • Similarly for the consumer, its associated output is sent (received by the consumer).

If the Transaction rollback is done – (jmsContext.rollback())

  • Its produced messages are destroyed.
  • Its consumed messages are recovered (not deleted from the JMS-Server).

Let us look at the code example to get a better understanding of its functionalities. Link to GitHub code repo.

Java
package lab07.transactons.example;

import labxx.common.settings.CommonSettings;
import javax.jms.*;

public class TransactionExample {
  public static void main(String[] args) {

    ConnectionFactory connectionFactory = CommonSettings.getConnectionFactory();
    Queue queue = CommonSettings.getDefaultQueue();

    Thread messageproducer = new Thread() {
      public void run() {
        try (JMSContext jmsContext = connectionFactory.createContext(JMSContext.SESSION_TRANSACTED)) {
          JMSProducer producer = jmsContext.createProducer();
          producer.send(queue, "This is a SESSION_TRANSACTED message");
          producer.send(queue, "Sending another message");
          //TODO - Comment and see the result, message is not delivered until committed
          sleep(5000);
          jmsContext.commit(); //Important
          //Next message is never delivered as it is rollback()
          producer.send(queue, "This message will not be delivered");
          jmsContext.rollback();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    };
  
    Thread messageConsumer = new Thread() {
      public void run() {
        try (JMSContext jmsContext = connectionFactory.createContext(JMSContext.SESSION_TRANSACTED)) {
          JMSConsumer consumer = jmsContext.createConsumer(queue);
          consumer.setMessageListener(msg -> {
            try {
              System.out.println(msg.getBody(String.class));
            } catch (JMSException e) {
              e.printStackTrace();
            }
          });
          jmsContext.commit();
          Thread.sleep(6000);
          consumer.close();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    };
 
    messageproducer.start();
    messageConsumer.start();
  }
}

Output

This is a SESSION_TRANSACTED message
Sending another message

When you run the code in your IDE, you will notice that there are just 2 messages printed on your terminal after 5-seconds as shown above. Until the message producer’s transaction is committed, the consumer does not receive any message. The consumer never receives the 3rd message (line-24), as the transaction rollback is done.

As you noticed, JMS Session is transacted using JMSContext.SESSION_TRANSACTED .

JMS Transactions are used when you want to control the messages that are sent and the messages that get delivered to the

By |Last Updated: April 3rd, 2024|Categories: Java™, JMS|

Table of Contents