我们有一个Spring JMS消息监听器容器,用于异步接收消息。使用DefaultMessageListenerContainer并在sessionTransacted模式下。我知道处于sessionTransacted模式意味着在异常情况下消息将被放回队列中。但是,即使接收者(选择了消息)崩溃或只是运行它的机器断电,我怎样才能确保消息不会从队列中删除?
起初我认为CLIENT_ACKNOWLEDGE确认模式应该救我,但apparently不是这样,Spring调用.acknowledge()无论如何。
所以这是我的问题,我怎样才能保证交货?使用自定义MessageListenerContainer?使用事务管理器?
使用事务处理会话并通过调用Session
类的commit()
方法指示成功的消息处理。
请查看19.4.5. Processing messages within transactions部分以了解配置。 (你可以使用DefaultMessageListenerContainer
)。根据您对消息的处理方式,您可能需要JTA事务管理器。
具有Client_Acknowledge模式的Spring消息侦听器将在客户端调用message.acknowledge()时确认该消息。
但是,如果在成功执行消息之后,消费者没有从客户端找到任何确认,则spring假定执行成功并确认该消息。
如果在任何时候,消费者在处理消息时遇到异常,则Spring侦听器需要知道发生了一些异常,以便将消息重新发送到队列以供另一个消费者线程获取它。如果您正在捕获异常,则spring假定所有内容都已处理并且执行顺利,因此会确认消息。
Spring消息监听器只允许从onMessage监听器抛出JMS异常。捕获自定义异常并从侦听器抛出JMS异常(在记录错误以供将来参考之后)将允许您重新传递消息。
或者您可以在非交易会话中使用Session.AUTO_ACKNOWLEDGE,请参阅下面的article报价
从receive()方法成功返回时,将自动确认消息。如果接收方使用MessageListener接口,则在从onMessage()方法成功返回时,将自动确认该消息。如果在执行receive()方法或onMessage()方法时发生故障,则会自动重新传递消息。 JMS提供程序仔细管理消息重新传递,并保证一次性传递语义。