dcsimg
Guaranteeing once-and-only-once processing
0 posts in topic
Flat View  Flat View
TOPIC ACTIONS:
 

Posted By:   David_McCullough
Posted On:   Monday, February 13, 2006 07:42 PM

Hello, I’d like some input on how to process a given persistent message only once. I think I understand the rules, but I want to make sure I’m on track here. From my reading of JMS workings, it appears that if in any case a message is delivered, but fails to be acknowledged by a client, it will be sent again (with message.JMSRedelivered == true). Now assuming that the session is in AUTO_ACKNOWLEDGE mode, suppose a message gets delivered, the on Message() call completes without any exceptions, but an exception is thrown in the JMS provider client code sometime after onMessage(), but before the code sent the acknowledgement successfully. The message would end up being sent again, correct? My next question   More>>

Hello,


I’d like some input on how to process a given persistent message only once. I think I understand the rules, but I want to make sure I’m on track here.


From my reading of JMS workings, it appears that if in any case a message is delivered, but fails to be acknowledged by a client, it will be sent again (with message.JMSRedelivered == true). Now assuming that the session is in AUTO_ACKNOWLEDGE mode, suppose a message gets delivered, the on Message() call completes without any exceptions, but an exception is thrown in the JMS provider client code sometime after onMessage(), but before the code sent the acknowledgement successfully. The message would end up being sent again, correct?


My next questions regard running in CLIENT_ACKNOWLEDGE mode and acknowledging messages manually. Message.acknowledge() is synchronous, correct? If this method returns normally, the server really got the ack, and you’re guaranteed not to get the same message again, right?


So, if the above are correct, I see a couple of ways to guard against duplicate messages.


The first would be to run in AUTO_ACKNOWLEDGE mode have a table in a database that kept the JMSMessageIDs of the processed messages and check against this before processing the new message.


The second way would be to run in CLIENT_ACKNOWLEDGE mode, and have code like this in onMessage():



			
try {
// process the message
…

message.acknowledge()
}
catch (Exception excp) {
// undo any partial message processing – message will be sent again
…
}



Lastly, how does all this work with MDBs? Does the container/provider always handle the acknowledgement, or is there a mode where you can acknowledge manually? Assuming the container/provider is doing the acknowledgement, what happens if the MDB is doing some container managed transaction, but the acknowledgment fails? Will the transaction get rolled back?


Thanks!

   <<Less
About | Sitemap | Contact