如何确保消息确认仅删除直到在jms代理中调用了确认的消息为止的消息。
目前,我有一个从jms队列中消费并对其进行部分处理的系统,有时稍后这些消息的批处理将被另一个线程保留。我现在需要确认消息。但是问题是我必须停止使用这些消息,否则确认先前收到的消息还将确认收到的所有其他后续消息。
换句话说,假设我在队列中有10条消息。我消耗了其中的7个,然后在第5条消息中确认。反过来,这会从队列中删除消费者收到的所有7条消息。有一种方法只能确认并从队列中删除消息,直到第5条消息为止。
编辑:我曾尝试创建两个会话并从不同的会话使用,但是(与Apache Qpid Atleast)这执行不一致。我的意思是不一致的,有时在测试过程中,无论您等待多长时间,一个消费者都能够接收消息,而另一个消费者却根本无法接收消息。这本来可以作为我的解决方案,但由于不一致,因此无法将其用作解决方案。
最佳答案
我知道这篇文章已经过时了,但是这个答案应该让以后偶然发现它的人受益。
如果您希望对要确认的消息进行精细控制,individual
确认方法应该可以为您提供帮助。使用此确认模式,您可以确认会话中的各个消息。尚未确认的邮件将重新发送。
这不是规范的一部分,但是大多数队列提供程序都在规范之外支持它。
Oracle
为了获得更大的灵活性,Message Queue允许您自定义JMS
客户端确认模式。在客户端确认模式下,客户端
通过调用
消息对象的accept()方法。
的标准行为
此方法将导致会话确认所有
自上次以来,该会话中的任何消费者都已消费了
该方法被调用。 (即,会话确认当前
消息以及所有先前未确认的消息,无论谁
消耗了它们。)
除了JMS指定的标准行为,Message Queue
使您可以使用客户端确认模式来确认一条消息。
时间。
public interface com.sun.messaging.jms.Message {
void acknowledgeThisMessage() throws JMSException;
void acknowledgeUpThroughThisMessage() throws JMSException;
}
ActiveMQ
可以想象其他的确认模式也会有用,因为
示例:CONSUMER_ACKNOWLEDGE,其中Message.acknowledge()将
只确认在特定MessageConsumer上收到的消息,
或CONSUMER_CHECKPOINT_ACKNOWLEDGE,其中Message.acknowledge()将
只确认直到(包括)该消息为止的消息
调用该方法的实例。
但是,如果不承担所有这些各种不同的可能性,
是否可以考虑仅添加INDIVIDUAL_ACKNOWLEDGE
模式?仅此一项就可以使多线程应用程序成为可能
实现他们需要的任何行为。
connection.createQueueSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
我没有亲自使用QPID,但是documentation hints可能会出现单个消息提示。
Examples
# acknowledge all received messages
session.acknowledge
# acknowledge a single message
session.acknowledge :message => message
在处理批处理时,您可以确认收到并处理的每条消息。如果遇到异常,请不要确认该消息。