How to simulate message redelivery in AUTO_ACKNOWLEDGE JMS Session Scenario?

大城市里の小女人 提交于 2019-12-03 07:52:15

Apparently the source of documentation I was looking yesterday Creating Robust JMS Applications mislead me in a way (or I might have understood it incorrectly). Especially that excerpt:

Until a JMS message has been acknowledged, it is not considered to be successfully consumed. The successful consumption of a message ordinarily takes place in three stages.

  1. The client receives the message.
  2. The client processes the message.
  3. The message is acknowledged. Acknowledgment is initiated either by the JMS provider or by the client, depending on the session acknowledgment mode.

I assumed AUTO_ACKNOWLEDGE does exactly that - acknowledged the message after the listener method returns a result. But according to the JMS specification it is a bit different and Spring listener containers as expected do not try to alter the behavior from the JMS specification. This is what the javadoc of AbstractMessageListenerContainer has to say - I've emphasized the important sentences:

The listener container offers the following message acknowledgment options:

  • "sessionAcknowledgeMode" set to "AUTO_ACKNOWLEDGE" (default): Automatic message acknowledgment before listener execution; no redelivery in case of exception thrown.
  • "sessionAcknowledgeMode" set to "CLIENT_ACKNOWLEDGE": Automatic message acknowledgment after successful listener execution; no redelivery in case of exception thrown.
  • "sessionAcknowledgeMode" set to "DUPS_OK_ACKNOWLEDGE": Lazy message acknowledgment during or after listener execution; potential redelivery in case of exception thrown.
  • "sessionTransacted" set to "true": Transactional acknowledgment after successful listener execution; guaranteed redelivery in case of exception thrown.

So the key to my solution is listenerContainer.setSessionTransacted(true);

Another issue I faced was that the JMS provider keeps redelivering the failed message back to the same consumer that had failed during the processing of the message. I don't know if the JMS specification gives a prescription what the provider should do in such situations, but what have worked for me was to use listenerContainer.shutdown(); in order to disconnect the failing consumer and allow the provider to redeliver the message and give a chance to another consumer.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!