有和没有Spring JMS的AUTO_ACKNOWLEDGEMENT模式之间的区别

时间:2015-02-10 07:42:37

标签: jms messaging spring-jms

我试图了解确认模式在JMS中的工作原理。我正在阅读这个来源,这让我很困惑,因为它与Spring的文档所说的相矛盾。

消息来源说一件事: 来自http://www.javaworld.com/article/2074123/java-web-development/transaction-and-redelivery-in-jms.html

  

从receive()方法成功返回时,将自动确认消息。如果接收方使用MessageListener接口,则在从onMessage()方法成功返回时,将自动确认该消息。如果在执行receive()方法或onMessage()方法时发生故障,则会自动重新传递消息。

来自http://www2.sys-con.com/itsg/virtualcd/Java/archives/0604/chappell/index.html

  

使用AUTO_ACKNOWLEDGE模式,确认总是在onMessage()处理程序返回后隐式发生的事情。通过在使用会话中指定CLIENT_ACKNOWLEDGE模式,接收消息的客户端可以对保证消息的传递进行更细粒度的控制。

Spring Docs说其他事情: 来自http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jms/listener/AbstractMessageListenerContainer.html

  

侦听器容器提供以下消息确认选项:

“sessionAcknowledgeMode”设置为“AUTO_ACKNOWLEDGE”(默认值):在侦听器执行之前自动确认消息;如果抛出异常,则无法重新发送。 “sessionAcknowledgeMode”设置为“CLIENT_ACKNOWLEDGE”:成功侦听器执行后自动确认消息;如果抛出异常,则无法重新发送。 “sessionAcknowledgeMode”设置为“DUPS_OK_ACKNOWLEDGE”:在侦听器执行期间或之后的延迟消息确认;在例外抛出的情况下潜在的重新发送。 “sessionTransacted”设置为“true”:成功监听器执行后的事务确认;在发生例外的情况下保证重新发送。

我想知道的是,为什么这些来源会说不同的东西?如果一切都是真的那么我怎么知道我的消息将如何/何时被确认?

1 个答案:

答案 0 :(得分:3)

你错过了抽象容器javadocs中的关键短语......

The exact behavior might vary according to the concrete listener container and JMS provider used.

Spring中使用的最常用的侦听器容器是DefaultMessageListenerContainer执行表现出该行为 - 它用于事务(本地或外部事务)经理),以便能够回滚已经确认的消息。在接收方法之后调用其侦听器,因此已经应用了标准JMS auto-ack。线程上的任何JmsTemplate操作也可以使用相同的会话 - 因此可以成为事务的一部分。

另一方面,SimpleMessageListenerContainer使用传统的MessageListener并展示标准的JMS行为(在Consumer返回之前从receive()调用侦听器;因此例外将停止ack)。

我建议你阅读那些具体实现的javadoc。来自SMLC ...

This is the simplest form of a message listener container. It creates a fixed 
number of JMS Sessions to invoke the listener, not allowing for dynamic 
adaptation to runtime demands. Its main advantage is its low level of 
complexity and the minimum requirements on the JMS provider: Not even the 
ServerSessionPool facility is required.

See the AbstractMessageListenerContainer javadoc for details on acknowledge 
modes and transaction options.

For a different style of MessageListener handling, through looped 
MessageConsumer.receive() calls that also allow for transactional reception of 
messages (registering them with XA transactions), see 
DefaultMessageListenerContainer.

我将为抽象容器上的文档打开一个JIRA问题,因为我可以看到它可能会产生误导。