我读了这个问题(Multithreaded JMS code : CLIENT_ACKNOWLEDGE or transacted session),但我不明白消息使用者中这两种方法之间的区别是什么:
CLIENT_ACKNOWLEDGE
模式。我们收到多条消息,然后收到一条acknowledge()
。xa
)。会话处于AUTO_ACKNOWLEDGE
模式。我们收到多条消息,然后执行commit()
。这是否取决于消息提供者的行为?
我认为,仅从一个目标接收邮件时,没有太大区别。可以使用CLIENT_ACKNOWLEDGE或事务处理的会话。
但是,如果在一个会话中使用多个目标,例如从队列中接收消息,然后对其进行处理并将处理结果发布到同一会话中的另一个主题,则更适合进行事务处理的会话。因此,接收和发布消息都将在一个事务中发生。根据消息处理的结果,可以提交事务或回滚事务。
如果进行会话,则acknowledgeMode
被忽略。这就是为什么在JMS 2.0中添加了新的单参数createSession(int)
使其更直观的原因。因此,没有诸如“以自动确认模式进行的会话”之类的事情。您有一个transacted或一个auto-acknowledged会话。在事务处理的会话中对Message.acknowledge()
的调用将被忽略(JMS API为specified)。
那么有什么区别?并不是您使用一个或多个目的地,因为互联网上有多个位置(包括此处的另一个答案)。这取决于会话是仅消费还是消费产生。如果仅使用它(您不产生任何消息),则两种模式都相同:调用Message.acknowledge()
或Session.commit()
会确认会话中收到的所有消息。即使从多个队列接收到。
消费生产会话的行为:
MessageProducer.send()
方法返回后,将立即提交client-acknowledge:发送的消息。调用Message.acknowledge()
时,客户端消息立即全部被确认。规范中没有特别提到,但我认为如果代理在确认了一半的消息后失败,则客户端将报告错误,并且仅保留部分消息。这给了您至少一次保证:如果您在过程结束时确认,并且程序中途失败,则输出消息将产生两次。
transactional:已发送的消息是原子提交的,并确认会话中所有已接收的消息。客户端或代理方的任何故障都不会导致仅生成或确认一部分消息。这为您提供一次精确的处理保证。