CLIENT_ACKNOWLEDGE vs Session.commit() 在消费者端 - JMS.



我读了这个问题(多线程JMS代码:CLIENT_ACKNOWLEDGE或事务处理会话),但我不明白消息消费者中的这两种方法有什么区别:

  1. 连接未事务处理。会话处于CLIENT_ACKNOWLEDGE模式。我们收到多条消息,然后一条acknowledge().
  2. 连接已事务处理(不是xa)。 会话处于AUTO_ACKNOWLEDGE模式。 我们收到多条消息,然后执行commit()

这是否取决于消息提供程序的行为?

如果会话已事务化,则忽略acknowledgeMode。这就是为什么在 JMS 2.0 中添加了新的单参数createSession(int)以使其更加直观。因此,没有"自动确认模式下的事务处理会话"这样的事情。您有事务处理自动确认的会话。事务处理会话中对Message.acknowledge()的调用将被忽略(它由 JMS API 指定)。

那么有什么区别呢?这不是你是否使用一个或多个目的地,正如互联网上的多个地方声称的那样(包括这里的另一个答案)。这取决于会话是仅消费还是消费生产。如果它是仅消费的(您不生成任何消息),则两种模式是相等的:调用 Message.acknowledge()Session.commit() 确认会话中收到的所有消息。即使从多个队列接收。

消费-生产会话的行为:

  • 客户端确认:MessageProducer.send()方法返回后,将立即提交已发送的消息。调用 Message.acknowledge() 时,将立即确认所有客户端消息。规范中没有特别提到这一点,但我认为如果代理在处理了一半的 msg 后失败,客户端将报告错误,只有部分消息将保持挂起状态。这为您提供了至少一次的保证:如果您在流程结束时确认并且程序中途失败,则输出消息将生成两次。

  • 事务性:发送的消息以原子方式提交,同时确认会话中所有收到的消息。客户端或代理端的任何故障都不能导致仅生成或确认部分消息。这为您提供了恰好一次的处理保证。它甚至更快:正如此处或此处所声称的,如果您在一个事务中生成多条消息,则MessageProducer.send()方法将是异步的,commit()方法将等待所有发送批量完成。

我认为

当只从一个目的地接收消息时没有太大区别。可以使用CLIENT_ACKNOWLEDGE或事务处理会话。

但是,当在一个会话中使用多个目标时,例如从队列接收消息,然后处理它并将流程结果发布到同一会话中的另一个主题,事务处理会话更适合。 因此,接收和发布消息都将在一个事务中发生。根据消息处理的结果,可以提交或回滚事务。

最新更新