使用和不使用 Spring JMS 的 AUTO_ACKNOWLEDGEMENT 模式之间的区别

xab*_*bhi 4 messaging jms 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”:成功监听器执行后的事务确认;在抛出异常的情况下保证重新交付。

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

Gar*_*ell 5

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

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

在使用最常用的侦听容器SpringDefaultMessageListenerContainer确实表现出的行为-这是旨在与交易使用(无论是本地或外部事务管理器),才能有回滚一个已经确认的消息的能力。它的侦听器接收方法之后被调用,因此标准的 JMS 自动确认已经被应用。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.
Run Code Online (Sandbox Code Playgroud)

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