JMS以前的消息确认

时间:2014-03-27 18:04:59

标签: java jms

我正在尝试解决以下问题:

我正在使用消息,但是在依赖于正确消息处理的系统中停机(例如数据库)

我正在使用CLIENT_ACKNOWLEDGE,并且在没有抛出异常时只调用.acknowledge()方法。

当我抛出异常,消息未被确认,并且我可以看到未确认的队列构建时,这很好。但是,这些消息都已经传递给消费者。

现在假设数据库重新联机,并且成功处理了任何新消息。所以我打电话给他们。我读到,调用.acknowledge()不仅确认该消息,还确认消费者以前收到的所有消息。

这不是我想要的!我需要重新传递/重试这些以前未确认的消息。我希望将它们保留在队列中并让JMS处理重试,因为在消费者中维护一个Collection,以便重试消息"可能会冒这些消息的风险(因为.acknowledge已经熟悉所有这些消息+说硬件失败了。)

有没有办法明确承认特定的消息而没有这个"确认所有先前的消息"行为?

2 个答案:

答案 0 :(得分:3)

JMS规范未定义确认特定消息。因此,一些JMS实现者提供每个消息确认,而另一些则不提供。您需要检查JMS提供程序文档。

消息队列通常可以选择如何将消息传递到客户端,先进先出(FIFO)或基于优先级。选择FIFO选项,以便按照它们进入队列的相同顺序传递所有消息。当数据库脱机并返回时,请调用recover方法再次以相同的顺序重新传递所有消息。

答案 1 :(得分:0)

在第一个未经处理的消息无法重新启动消息传递后,您需要在会话中调用recover。来自JMS 1.1规范第4.4.11节

  

当使用CLIENT_ACKNOWLEDGE模式时,客户端可能会建立一个大的模式   尝试处理它们时未确认的消息数。一个   JMS提供程序应该为管理员提供限制客户端的方法   过度运行,以便客户不会被资源耗尽   当他们正在使用的某些资源暂时出现故障   阻止。

     

会话的恢复方法用于停止会话并重新启动它   第一个未经确认的消息。实际上,会议的系列   传递的消息被重置为最后一个之后的点   公认的信息。它现在提供的消息可能不同   来自那些由于邮件过期而最初交付的邮件   以及更高优先级消息的到来。