tags:

views:

114

answers:

2

Hi,

We've a Spring JMS message listener container for receiving messages asynchronously. Using DefaultMessageListenerContainer and in sessionTransacted mode. I understand being in sessionTransacted mode means in case of an exception the message will be put back into the queue. But how can I make sure the message won't be deleted from the queue even if the receiver (which is picked the message) crashes or just the machine running it looses power?

At first I thought CLIENT_ACKNOWLEDGE acknowledge mode should save me, but apparently it's not the case, Spring calls .acknowledge() no matter what.

So here's my question, how can I guarantee the delivery? Using a custom MessageListenerContainer? Using a transaction manager?

+1  A: 

Use a transacted session and indicate successful message processing by invoking the Session class's commit() method.

Check the section 19.4.5. Processing messages within transactions for the configuration. (you can use a DefaultMessageListenerContainer). Depending on what you're doing with the messages, you may need a JTA transaction manager.

Pascal Thivent
A: 

or you can use Session.AUTO_ACKNOWLEDGE with nontransacted session, see quote below from this article

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.

soody
-1 because the conclusion drawn from this document is incorrect. Yes, there is redelivery if the receive() or onMessage() call fails but this does not mean the receiver has had a chance to do something with the message. If the receiver crashes at this point, the message is irretrievably lost which is what OP was trying to avoid. However, using a transacted session and explicit commit calls as described in the other response does prevent such loss of messages if the receiver crashes.
T.Rob
So in nutshell the article is misleading? What is meaning of crash? if onMessage method does not return due to crash wouldn't the message will be re-delivered?
soody
I'm not saying the article is misleading, just that it doesn't apply to the original question. All of the failures discussed in the article quote happen before the message is returned to the app. OP wanted to delay message acknowledgment until after the message was returned and the app had processed it, as CLIENT_ACKNOWLEDGE is supposed to provide. Setting Session.AUTO_ACKNOWLEDGE actually enforces the behavior OP was trying to prevent.
T.Rob