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