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