我正在尝试解决以下问题:
我正在使用消息,但是在依赖于正确消息处理的系统中停机(例如数据库)
我正在使用CLIENT_ACKNOWLEDGE,并且在没有抛出异常时只调用.acknowledge()方法。
当我抛出异常,消息未被确认,并且我可以看到未确认的队列构建时,这很好。但是,这些消息都已经传递给消费者。
现在假设数据库重新联机,并且成功处理了任何新消息。所以我打电话给他们。我读到,调用.acknowledge()不仅确认该消息,还确认消费者以前收到的所有消息。
这不是我想要的!我需要重新传递/重试这些以前未确认的消息。我希望将它们保留在队列中并让JMS处理重试,因为在消费者中维护一个Collection,以便重试消息"可能会冒这些消息的风险(因为.acknowledge已经熟悉所有这些消息+说硬件失败了。)
有没有办法明确承认特定的消息而没有这个"确认所有先前的消息"行为?
答案 0 :(得分:3)
JMS规范未定义确认特定消息。因此,一些JMS实现者提供每个消息确认,而另一些则不提供。您需要检查JMS提供程序文档。
消息队列通常可以选择如何将消息传递到客户端,先进先出(FIFO)或基于优先级。选择FIFO选项,以便按照它们进入队列的相同顺序传递所有消息。当数据库脱机并返回时,请调用recover方法再次以相同的顺序重新传递所有消息。
答案 1 :(得分:0)
在第一个未经处理的消息无法重新启动消息传递后,您需要在会话中调用recover。来自JMS 1.1规范第4.4.11节
当使用CLIENT_ACKNOWLEDGE模式时,客户端可能会建立一个大的模式 尝试处理它们时未确认的消息数。一个 JMS提供程序应该为管理员提供限制客户端的方法 过度运行,以便客户不会被资源耗尽 当他们正在使用的某些资源暂时出现故障 阻止。
会话的恢复方法用于停止会话并重新启动它 第一个未经确认的消息。实际上,会议的系列 传递的消息被重置为最后一个之后的点 公认的信息。它现在提供的消息可能不同 来自那些由于邮件过期而最初交付的邮件 以及更高优先级消息的到来。