Programming Tutorials Browser Tutorials Articles Struts Tutorials Hibernate Tutorials

  Tutorial: Transaction and redelivery in JMS

Transaction and redelivery in JMS

Tutorial Details:

Transaction and redelivery in JMS
Transaction and redelivery in JMS
By: By Prakash Malani
Make the right transaction decision for your message delivery
rchitecting and designing applications with the Java Message Service (JMS) requires not only knowing how to use the JMS API, but also having a solid foundation of its concepts. This article focuses on two such powerful concepts: transaction and redelivery . In JMS, a transaction organizes a message or message group into an atomic processing unit; failure to deliver a message may result in redelivery of that message or message group.
In this article, I help you develop a thorough understanding of your transaction options and show how you can evaluate their impact on message redelivery. I assume you have some familiarity with the JMS API as well as message-driven beans (MDBs).
Transaction option overview
An application has myriad transaction options available, including whether or not it wants to participate in transactions. If your application does not use transactions, it can use one of these acknowledgement modes: auto, duplicates okay, and client. You specify the acknowledgement modes when creating a JMS session. If your application uses transactions, it can choose from these transaction options: transacted session, MDB with container-managed transaction demarcation (CMTD), and MDB with bean-managed transaction demarcation (BMTD). The following lists briefly describe these acknowledgement modes and transaction options.
Acknowledgement options:
Auto mode: When a session uses auto mode, the messages sent or received from the session are automatically acknowledged. This is the simplest mode and expresses JMS's power by enabling once-only message delivery guarantee.
Duplicates okay mode: When a session uses duplicates okay mode, the messages sent or received from the session are automatically acknowledged just like auto mode, albeit lazily. Under rare circumstances, the messages might be delivered more than once. This mode enables at-least-once message delivery guarantee.
Client mode: When a session uses client mode, the messages sent or received from the session are not acknowledged automatically. The application must acknowledge the message receipt. This mode gives the application (rather than the JMS provider) complete control over message acknowledgement, at the cost of increased code complexity.
Other types of acknowledgement modes are possible. However, these acknowledgement modes are JMS provider specific, and therefore, compromise the JMS application portability.
Transaction options:
Transacted session: An application can participate in a transaction by creating a transacted session (or local transaction). The application completely controls the message delivery by either committing or rolling back the session.
Message-driven beans with CMTD: An MDB can participate in a container transaction by specifying CMTD in the XML deployment descriptor. The transaction commits upon successful message processing or the application can explicitly roll it back.
Message-driven beans with BMTD: An MDB can choose not to participate in a container transaction by specifying BMTD in the XML deployment descriptor. The MDB programmer has to design and code programmatic transactions.
Figure 1 depicts a decision tree of the previously mentioned transaction options.
Figure 1. Transaction options decision tree
Before studying the transaction options in detail, we'll explore the message delivery process.
Message delivery stages
Toward the end of delivery, the message conceptually passes through the following stages: message with JMS provider and message in application processing.
Message with JMS provider
In this stage, the message stays with the JMS provider just before the provider delivers it to the application. Consider a catastrophic situation where the JMS provider fails. What happens to the messages that the provider has not yet delivered to the client? Will the messages be lost?
The messages' fate depends not upon the transaction options outlined earlier, but rather upon the delivery mode. There are two delivery modes: nonpersistent and persistent . Messages with nonpersistent delivery modes are potentially lost if the JMS provider fails. Messages with persistent delivery modes are logged and stored to a stable storage. The JMS provider saves these messages to a stable storage, such as a database or a file system, and eventually delivers them to the application for processing.
Message in application processing
In this stage, the application receives the message from the JMS provider and processes it. Consider a failure occurring during message processing. What happens to the message? Will the message be lost or redelivered for successful processing later? The answers to these questions depend upon the transaction options you choose.
Figure 2 depicts the two processing stages. The diagram shows that a message moves from the JMS provider to application processing.
Figure 2. Message delivery stages
Throughout the remainder of the article, I use the action legend shown in Figure 3 to illustrate the different transaction options. As Figure 3 shows, a filled arrow depicts a JMS provider-performed action, whereas an outlined arrow depicts an application-performed action.
Figure 3. Action legend
The setup
To demonstrate the impact of various transaction options as well as redelivery, I will use one sender. The sender sends simple integers as object messages to a queue. Each transaction option has a different receiver. Each receiver demonstrates the impact of choosing a particular transaction option as well as highlights the impact on message redelivery. The sender and receivers utilize common administered objects: connection factory and queue. The connection factory is available using the Java Naming and Directory Interface (JNDI) name jms/QueueConnectionFactory , whereas the queue is available using the jms/Queue JNDI name.
Listing 1 shows the code for the sender:
Listing 1. Sender
package com.malani.examples.jms.transactions;
import javax.naming.InitialContext;
import javax.jms.*;
public class Sender {
public static void main(String[] args) {
System.out.println("Starting...");
QueueConnectionFactory aQCF = null;
QueueConnection aQC = null;
QueueSession aQS = null;
QueueSender aSender = null;
try {
InitialContext aIC = new InitialContext(Resource.getResources());
aQCF = (QueueConnectionFactory) aIC.lookup(
iConstants.FACTORY_NAME
);
aQC = aQCF.createQueueConnection();
aQS = aQC.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue aQueue = (Queue) aIC.lookup(iConstants.QUEUE_NAME);
aSender = aQS.createSender(aQueue);
aQC.start();
for (int i = 0; i < 10; i++) {
aSender.send(aQS.createObjectMessage(new Integer(i)));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (aSender != null) {
aSender.close();
}
if (aQS != null) {
aQS.close();
}
if (aQC != null) {
aQC.stop();
aQC.close();
}
} catch (JMSException e) {
e.printStackTrace();
}
}
System.out.println("Ending...");
}
}
The following sections describe each acknowledgement mode in detail. A receiver demonstrates each acknowledgement mode. Each case uses the sender above to demonstrate the impact and implications of implementing a specific transaction option.
Auto acknowledgement
To implement the auto acknowledgement mode, when you create the receiver's session, specify false as the first argument and Session.AUTO_ACKNOWLEDGE as the second argument of the createSession() factory method. Specifying false creates a nontransacted session. The second parameter creates a session that automatically acknowledges messages. A message is automatically acknowledged when it successfully returns from the receive() method. If the receiver uses the MessageListener interface, the message is automatically acknowledged when it successfully returns from the onMessage() method. If a failure occurs while executing the receive() method or the onMessage() method, the message is automatically redelivered. The JMS provider carefully manages message redelivery and guarantees once-only delivery semantics.
Listing 2 describes the Receiver class. The Receiver is the AutoReceiver class's superclass. The Receiver superclass does most of the heavy lifting. It receives the object messages sent by the Sender class. In the processMessage() method, the receiver prints the message:
Listing 2. Receiver
package com.malani.examples.jms.transactions;
import javax.jms.*;
import javax.naming.InitialContext;
import java.io.InputStreamReader;
public abstract class Receiver {
protected void doAll() {
QueueConnectionFactory aQCF = null;
QueueConnection aQC = null;
QueueSession aQS = null;
QueueReceiver aQR = null;
try {
InitialContext aIC = new InitialContext(Resource.getResources());
aQCF = (QueueConnectionFactory) aIC.lookup(
iConstants.FACTORY_NAME
);
aQC = aQCF.createQueueConnection();
aQS = createQueueSession(aQC);
final QueueSession aQS1 = aQS;
Queue aQueue = (Queue) aIC.lookup(iConstants.QUEUE_NAME);
aQR = aQS.createReceiver(aQueue);
MessageListener aML = new MessageListener() {
public void onMessage(Message aMessage) {
try {
processMessage(aMessage, aQS1);
} catch (JMSException e) {
e.printStackTrace();
}
}
};
aQR.setMessageListener(aML);
aQC.start();
InputStreamReader aISR = new InputStreamReader(System.in);
char aAnswer = ' ';
do {
aAnswer = (char) aISR.read();
if ((aAnswer == 'r') || (aAnswer == 'R')) {
aQS.recover();
}
} while ((aAnswer != 'q') && (aAnswer != 'Q'));
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (aQR != null) {
aQR.close();
}
if (aQS != null) {
aQS.close();
}
if (aQC != null) {
aQC.stop();
aQC.close();
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}
protected void processMessage(Message aMessage, QueueSession aQS) throws JMSException {
if (aMessage instanceof Ob


 

Read Tutorial at: Click here to view the tutorial

Rate Tutorial:
Transaction and redelivery in JMS

View Tutorial:
Transaction and redelivery in JMS

Related Tutorials:

Messaging makes its move, Part 2 - JavaWorld - March 1999
Messaging makes its move, Part 2 - JavaWorld - March 1999
 
JMS: An infrastructure for XML-based business-to-business communication - JavaWorld February 2000
JMS: An infrastructure for XML-based business-to-business communication - JavaWorld February 2000
 
Make room for JavaSpaces, Part 4 - JavaWorld April 2000
Make room for JavaSpaces, Part 4 - JavaWorld April 2000
 
Make room for JavaSpaces, Part 5 - JavaWorld June 2000
Make room for JavaSpaces, Part 5 - JavaWorld June 2000
 
Add the power of asynchronous processing to your JSPs - JavaWorld February 2001
Create custom JSP tags to use with JMS ost JavaServer Pages (JSP) developers that
 
Optimistic Locking pattern for EJBs - JavaWorld July 2001
Optimistic Locking pattern for EJBs - JavaWorld July 2001
 
To EJB, or not to EJB?
To EJB, or not to EJB?
 
Listen to heartbeats using JMS
Listen to heartbeats using JMS
 
Transaction and redelivery in JMS
Transaction and redelivery in JMS
 
Rumble in the jungle: J2EE versus .Net, Part 1
Rumble in the jungle: J2EE versus .Net, Part 1
 
Should you go with JMS?
Should you go with JMS?
 
Manage users with JMS
Manage users with JMS
 
Hermes JMS Browser
Hermes JMS Browser Hermes is a Swing application that allows you to interact with JMS providers.
 
Capture the benefits of asynchronous logging
Capture the benefits of asynchronous logging Develop an asynchronous log service using JMS and Hibernate This article will help you develop a simple log service. The service creates some log messages, sends them across the network to a JMS provider,
 
Using a JMS Provider with MDBs via the J2EE Connector Architecture
Using a JMS Provider with MDBs via the J2EE Connector Architecture In this article I will provide a brief introduction to MDB and the J2EE Connector Architecture (JCA), examining how MDBs can be deployed with the JCA 1.5 resource adapter to use a JMS pro
 
JMS Messaging Online Resource
JMS Messaging Online Resource JMS Tutorials JMS provides a way for Java programs to access an enterprise messaging system, also known as message oriented middleware (MOM). Check out the below tutorials.
 
Commons Transaction
Commons Transaction aims at providing lightweight, standardized, well tested and efficient implementations of utility classes commonly used in transactional Java programming. Initially there are implementations for multi level locks,
 
Distributed Enterprise Messaging with MantaRay
A very important communication standard in Java is Java Messaging Service (JMS). JMS is a set of Java interfaces and associated semantics that define a way for a Java-based client to access a messaging system. JMS provides a rich, yet simple, set of messa
 
A first look at Apache Geronimo
Start developing and deploying J2EE apps on the first open source J2EE server. When released, Geronimo will be the first J2EE-certified open source server. This article will give you the basics you need for developing and deploying J2EE applications on Ge
 
Getting Started with Java Message Service (JMS)
The Java Message Service (JMS) is designed to allow Java applications to use enterprise messaging systems. It makes it easy to develop enterprise applications that asynchronously send and receive business data and events. Learn how to implement it for you
 
Site navigation
 

 

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright © 2006. All rights reserved.