【问题标题】:CLIENT_ACKNOWLEDGE vs Session.commit() in consumer side - JMS消费者端的 CLIENT_ACKNOWLEDGE 与 Session.commit() - JMS
【发布时间】:2019-12-17 19:15:24
【问题描述】:

我看了这个问题(Multithreaded JMS code : CLIENT_ACKNOWLEDGE or transacted session)但我不明白这两种方法在消息消费者中有什么区别:

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

这取决于消息提供者的行为吗?

【问题讨论】:

    标签: jms


    【解决方案1】:

    如果会话被处理,acknowledgeMode 将被忽略。这就是为什么在 JMS 2.0 中添加了新的单参数 createSession(int) 以使其更直观的原因。所以没有“自动确认模式下的事务处理”之类的东西。您要么有一个已交易 或一个自动确认 会话。事务会话中对 Message.acknowledge() 的调用将被忽略(JMS API 为 specified)。

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

    消费-生产会话的行为:

    • client-acknowledge:MessageProducer.send() 方法返回后立即提交发送的消息。当调用Message.acknowledge() 时,客户端消息会立即得到确认。这在规范中没有特别提到,但我认为如果代理在 ack 一半的 msgs 后失败,客户端会报告错误,只有一部分消息会保持 acked。这为您提供了至少一次的保证:如果您在进程结束时确认并且您的程序中途失败,则输出消息将产生两次。

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

    【讨论】:

    • '一旦 MessageProducer.send() 方法返回就提交' - 我认为这里区分同步和异步消息发送很重要。以 ActiveMQ 为例 - activemq.apache.org/async-sends 很好地提供了一般解释
    • @misha2048 我会说 ActiveMQ 的非标准扩展。我们在此答案中记录了符合标准的行为。
    • 是的,绝对
    【解决方案2】:

    我认为从一个目的地接收消息时没有太大区别。可以使用 CLIENT_ACKNOWLEDGE 或 Transacted 会话。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-04
      • 2014-09-06
      • 1970-01-01
      • 1970-01-01
      • 2018-03-07
      • 1970-01-01
      • 2012-05-18
      相关资源
      最近更新 更多