JMSDeliveryMode — Purpose: Routing
There
are two types of delivery modes in JMS:
persistent and
nonpersistent. A persistent message should
be delivered
once-and-only-once, which means that a
message is not lost if the JMS provider fails; it will be delivered
after the server recovers. A nonpersistent message is delivered
at-most-once, which means that it can
be lost and never delivered if the JMS provider fails. In both
persistent and nonpersistent delivery modes the message server should
not send a message to the same consumer more than once, but it is
possible; see the section on JMSRedelivered
for
more details.
The vendor-supplied client runtime and the server functionality are collectively referred to as the JMS provider. A "provider failure" generically describes any failure condition that is outside of the domain of the application code. It could mean a hardware failure that occurs while the provider is entrusted with the processing of a message, or it could mean an unexpected exception or halting of a process due to a software defect. It could also mean a network failure that occurs between two processes that are part of the JMS vendor's internal architecture.
Persistent messages are intended to survive system failures of the JMS provider (the message server). Persistent messages are written to disk as soon as the message server receives them from the JMS client. After the message is persisted to disk the message server can then attempt to deliver the message to its intended consumer. As the messaging server delivers the message to the consumers it keeps track of which consumers successfully receive the message. If the JMS provider fails while delivering the message, the message server will pick up where it left off following a recovery. Persistent messages are delivered once-and-only-once. The mechanics of this are covered in greater detail in Chapter 6.
Nonpersistent messages are not written to disk when they are received by the message server, so if the JMS provider fails, the message will be lost. In general nonpersistent messages perform better than persistent messages. They are delivered more quickly and require less system resources on the message server. However, nonpersistent messages should only be used when a loss of messages due to a JMS provider failures is not an issue. The chat example used in Chapter 2 is a good example of a system that doesn't require persistent delivery. It's not critical that every message be delivered to all consumers in a chat application. In most business systems, however, messages are delivered using the persistent mode, because it's important that they be successfully delivered.
The delivery mode can be set using the setDeliveryMode(
)
method defined in both the
TopicPublisher
and QueueSender
message producers. The javax.jms.DeliveryMode
class defines the two constants used to declare the delivery mode:
PERSISTENT
and NON_PERSISTENT
:
// Publish-and-subscribe TopicPublisher topicPublisher = topicSession.createPublisher(topic);topicPublisher.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
// Point-to-point QueueSender queueSender = queueSession.createSender(queue);queueSender.setDeliverMode(DeliveryMode.PERSISTENT);
Once the delivery mode has been set on the message producer, it will
be applied to all the messages delivered by that producer. The
delivery mode can be changed at any time using the
setDeliveryMode( )
method; the new mode will be
applied to subsequent messages. The default delivery mode of a message
producer is always PERSISTENT
.
The delivery mode of a message producer can be overridden for an individual message during the send operation, which allows a message producer to deliver a mixture of persistent and nonpersistent messages to the same destination (topic or queue):
// Publish-and-subscribe Message message = topicSession.createMessage( ); topicPublisher.publish(message,DeliveryMode.PERSISTENT
, 5, 0); // Point-to-point Message message = queueSession.createMessage( ); queueSender.send(message,DeliveryMode.NON_PERSISTENT
, 5, 0);
The JMSDeliveryMode
can be obtained from the
Message
object using the
getJMSDeliveryMode(
)
method:
public void onMessage(Message message){
try {
if (message.getJMSDeliveryMode( )
== DeliveryMode.PERSISTENT){
// Do something
} else {
// Do something else
}
} catch (JMSException jmse){jmse.printStackTrace( );}
}