1
votes

I have a multiple consumer listening to a queue and when a message arrives its onMessage() function in invoked. Since there are multiple consumers, each consumer has its own session. The requirement is that the message should be acknowledged only if there is no issues and no exception is thrown...)

AUTO_ACK mode: My understanding is: the message is acknowledged after onMessage completes successfully. If there is an exception in onMessage(), the message will be redelivered. Client ack: At the end of onMessage(), I explicitly call acknowledge(). In case of error the acknowledge() method will not be called so message will be redelivered. Transacted Session: I call session.commit() at the end of the onMessage() function, in case of some exception I catch it and call session.rollback and hence the message will be redelivered.

The consumer is ABLE to detect duplicate messages and handle it appropriately. My question is that all the 3 modes are doing the same thing and solving my purpose, so which method is better than the other and why? In short why should I use transacted sessions over client ack or auto mode. I do not want to use JTA/XA as it is not supported by all jms providers example activeMQ and it will make my application slow.

If my consumer was NOT able to handle duplicate messages, then I understand that the only option I have is to use JTA/XA because all other options can send me the message again which will result in duplicate processing. In JTA/XA also I can get the message again but it would not be considered as duplicate processing as the previous transactions would have been rollbacked.

1

1 Answers

1
votes

Be careful here about the difference between ack modes as they can be more subtle than you might think.

When using auto acknowledge and throwing an exception in onMessage your message might get redelivered to another client, the same client, or go into a DLQ depending on your broker and how it's configured.

The thing that many people overlook with client acknowledge is that the client ack is actually acking all previous messages delivered for the parent Session, so if you had more than one consumer in the same session it's message could also be acked by your acknowledge call. Since in your case you have a consumer per session then you sort of fall back to the auto ack case where messages will get redelivered or might go to a DLQ.

In the local transaction case the messages are often times redelivered some number of times to the same client based on either client or Broker configuration before either being re-dispatched to some other consumer or are routed to a DLQ.

To some degree the mode you choose depends on bit on your expectations of the outcome of multiple failures and how you can configure your chosen Broker implementation to handle that.