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.
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