|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SYS-CON.TV |
TOP THREE LINKS YOU MUST CLICK ON Java EE 5 Guaranteed Messaging With JMS
Guaranteed Messaging With JMS
Apr. 1, 2001 12:00 AM
The notion of guaranteed delivery of Java Message Service messages has been lightly touched on in other recently published articles on JMS. But what really makes a JMS message "guaranteed"? Should you just take it on faith, or would you like to know what's behind it? This article answers these questions via a detailed discussion of message persistence, internal acknowledgment rules, and message redelivery. Using excerpts condensed from the book we coauthored, Java Message Service, we'll explain how JMS guaranteed messaging works - including once-and-only-once delivery semantics, durable subscriptions, failure and recovery scenarios, and transacted messages.
JMS Guaranteed Messaging
"Provider failure" refers to any failure condition that is outside 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, an unexpected exception, the abnormal end of a process due to a software defect, or network failures.
Message Autonomy
Once a JMS client sends a message, its role is completed. The JMS provider guarantees that any other interested parties will receive the message. This contract between a sending JMS client and the JMS provider is much like the contract between a JDBC client and a database. Once the data is delivered, it is considered "safe" and out of the hands of the client.
Store-and-Forward Messaging
Message Acknowledgments
The acknowledgment mode is set on a JMS session when it is created, as indicated below: tSession = tConnect.createTopicSession(false, Session.CLIENT_ACKNOWLEDGE); Session bean state is not transactional.
AUTO_ACKNOWLEDGE
The Producer's Perspective
The Server's Perspective
In a publish/subscribe model, the message server delivers a copy of a message to each of the subscribers. For durable subscriber, the message server doesn't consider a message fully delivered until it has received an acknowledgment from all of the message's intended recipients. It knows on a per-consumer basis which clients have received each message and which have not. Once the message server has delivered the message to all of its known subscribers and has received acknowledgments from each of them, the message is removed from its persistent store (see Figure 2). If the subscriptions are durable and the subscribers aren't currently connected, the message will be held by the message server until either the subscriber becomes available or the message expires. This is true even for nonpersistent messages. If a nonpersistent message is intended for a disconnected durable subscriber, the message server saves the message to disk as though it were a persistent message. In this case the difference between persistent and nonpersistent messages is subtle, but very important. For nonpersistent messages the JMS provider could fail before it's had a chance to write the message out to disk on behalf of the disconnected durable subscribers. Messages may be lost (see Figure 3). With persistent messages a provider may fail and recover gracefully, as illustrated in Figures 4 and 5. Since the messages are held in persistent storage, they're not lost and will be delivered to consumers when the provider starts up again. If the messages are sent using a p2p queue, they're guaranteed to be delivered. If the messages were sent via publish/subscribe, they're guaranteed to be delivered only if the consumers' subscriptions are durable.
The Consumer's Perspective
Message Redelivery
Point-to-Point Queues
From the receiver's perspective the rules are somewhat simpler since only one consumer can receive a particular instance of a message. A message stays in a queue until it is delivered to a consumer or expires. This is somewhat analogous to a durable subscriber in that a receiver can be disconnected while the message is being produced without losing the message. If the messages are nonpersistent they aren't guaranteed to survive a provider failure.
DUPS_OK_ACKNOWLEDGE
In practice, the performance improvement you gain from DUPS_OK_ACKNOWLEDGE may be something you want to measure before designing your application around it.
CLIENT_ACKNOWLEDGE
The use of CLIENT_ACKNOWLEDGE allows the application to control when the acknowledgment is sent. For example, an application can acknowledge a message - thereby relieving the JMS provider of its duty - and perform further processing of the data represented by the message. The key to this is the acknowledge() method on the Message object, as shown in Listing 1. The acknowledge() method informs the JMS provider that the message has been successfully received by the consumer. This method throws an exception to the client if a provider failure occurs during the acknowledgment process. The provider failure results in the message being retained by the JMS server for redelivery.
Transacted Messages
The JMS provider won't start delivery of the messages to its consumers until the producer has issued a commit() on the session. The scope of a JMS transaction can include any number of messages. JMS also supports transactional receives, in which a group of transacted messages are received by the consumer on an all-or-nothing basis (see Figure 9). From the transacted receiver's perspective the messages are delivered to it as expeditiously as possible, yet they are held by the JMS provider until the receiver issues a commit() on the session object. If a failure occurs or a rollback() is issued, the provider will attempt to redeliver the messages, in which case the messages will have the redelivered flag set. Transacted producers and transacted consumers can be grouped together in a single transaction if they are created from the same session object, as shown in Figure 10. This allows a JMS client to produce and consume messages as a single unit of work. If the transaction is rolled back, the messages produced within the transaction won't be delivered by the JMS provider. The messages consumed within the same transaction won't be acknowledged and will be redelivered. Unless you're doing a synchronous request/reply, you should avoid grouping a send followed by an asynchronous receive within a transaction. There could be a long interval between the time a message is sent and the related message is asynchronously received, depending on failures or downtime of other processes involved. It's more practical to group the receipt of a message followed by the send of another message.
Creating a JMS Transaction
The first parameter of createTopicSession() or createQueueSession() method is a Boolean indicating whether this is a transacted session. That is all we need to create a transactional session. There is no explicit begin() method. When a session is transacted, all messages sent or received using that session are automatically grouped in a transaction. The transaction remains open until either a session.rollback() or a session.commit() happens, at which point a new transaction is started. An additional Session method, isTransacted(), returns a Boolean true or false indicating whether the current session is transactional.
Distributed Transactions
Sometimes it's necessary to coordinate the send or receipt of a JMS transaction with the update of another non-JMS resource, like a database or an EJB entity bean. This typically involves an underlying transaction manager that takes care of coordinating the prepare, commit, or rollback of each resource participating in the transaction. JMS provides JTA transaction interfaces for accomplishing this. JMS providers that implement the JTA XA APIs can participate as a resource in a two-phase commit. The JMS specification provides XA versions of the following JMS objects : XAConnectionFactory, XAQueueConnection, XAQueueConnectionFactory, XAQueueSession, XASession, XATopicConnection, XATopicConnectionFactory, and XATopicSesion.
Conclusion
Through message acknowledgment, message persistence, and transactions, JMS provides a strict set of rules that guarantees that your business critical data will travel reliably throughout your global enterprise. Note: This material is condensed from our book, which contains full working examples with detailed explanations of the concepts presented here. YOUR FEEDBACK
LATEST JAVA STORIES & POSTS
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK SPONSORED BY INFRAGISTICS
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||