JMS消息仅在消息被确认之前确认

Rak*_*aks 4 java messaging jms qpid

如何确保消息确认仅删除直到在jms代理中调用了确认的消息之前的消息。目前,我有一个从jms队列中消费并对其进行部分处理的系统。有时稍后,这些消息的批处理将被另一个线程保留。我现在需要确认消息。但是问题是我必须停止使用这些消息,否则确认先前收到的消息还将确认所有其他后续收到的消息。

换句话说,假设我在队列中有10条消息。我消耗了其中的7个,然后在第5条消息中确认。反过来,这会从队列中删除消费者收到的所有7条消息。有一种方法只能确认并从队列中删除消息,直到第5条消息为止。

编辑:我曾尝试创建两个会话并从不同的会话使用,但是(使用Apache Qpid Atleast)这执行不一致。我的意思是不一致的,有时在测试过程中,无论您等待多长时间,一个消费者都能够接收消息,而另一个消费者却根本无法接收消息。这本来可以作为我的解决方案,但由于不一致,因此无法将其用作解决方案。

Dee*_*ala 5

我知道这篇文章已经过时了,但是这个答案应该让以后偶然发现它的人受益。

如果您希望对要确认的邮件进行精细控制,则individual确认方法应该可以为您提供帮助。使用此确认模式,您可以确认会话中的各个消息。尚未确认的邮件将重新发送。

这不是规范的一部分,但是大多数队列提供程序都在规范之外支持它。

甲骨文

为了获得更大的灵活性,Message Queue允许您自定义JMS客户端确认模式。在客户端确认模式下,客户端通过调用消息对象的accept()方法显式确认消息使用。

此方法的标准行为是使会话确认自上次调用该方法以来该会话中的任何使用者都已使用的所有消息。(也就是说,会话确认当前消息以及所有先前未确认的消息,而不管是谁消耗了它们。)

除了JMS指定的标准行为外,Message Queue还允许您使用客户端确认模式来一次确认一条消息。

public interface com.sun.messaging.jms.Message {
          void acknowledgeThisMessage() throws JMSException;
          void acknowledgeUpThroughThisMessage() throws JMSException;
}
Run Code Online (Sandbox Code Playgroud)

ActiveMQ

可以想象其他有用的确认模式,例如:CONSUMER_ACKNOWLEDGE,其中Message.acknowledge()仅确认在特定MessageConsumer上接收到的消息,或者CONSUMER_CHECKPOINT_ACKNOWLEDGE,其中Message.acknowledge()仅确认直到(包括)以下的消息。在其上调用该方法的Message实例。

但是,如果不采用所有这些不同的可能性,是否可以考虑仅添加INDIVIDUAL_ACKNOWLEDGE模式?仅此一项就可以使多线程应用程序实现所需的任何行为。

connection.createQueueSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
Run Code Online (Sandbox Code Playgroud)

我没有亲自使用QPID,但是文档提示可能会出现单个消息提示

Examples
  # acknowledge all received messages
  session.acknowledge

  # acknowledge a single message
  session.acknowledge :message => message
Run Code Online (Sandbox Code Playgroud)

处理批处理时,您可以确认收到并处理的每条消息。如果遇到异常,请不要确认该消息。