Difference between AUTO_ACKNOWLEDGEMENT mode with

2019-07-20 19:46发布

I am trying to understand how acknowledgement modes work in JMS. I was reading this source and it hugely confused me as it was contradicting what Spring's documentation says.

Sources saying one thing: From http://www.javaworld.com/article/2074123/java-web-development/transaction-and-redelivery-in-jms.html

A message is automatically acknowledged when it successfully returns from the receive() method. If the receiver uses the MessageListener interface, the message is automatically acknowledged when it successfully returns from the onMessage() method. If a failure occurs while executing the receive() method or the onMessage() method, the message is automatically redelivered.

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

With AUTO_ACKNOWLEDGE mode the acknowledgment is always the last thing to happen implicitly after the onMessage() handler returns. The client receiving the messages can get finer-grained control over the delivery of guaranteed messages by specifying the CLIENT_ACKNOWLEDGE mode on the consuming session.

Spring Docs saying other things: From http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jms/listener/AbstractMessageListenerContainer.html

The listener container offers the following message acknowledgment options:

"sessionAcknowledgeMode" set to "AUTO_ACKNOWLEDGE" (default): Automatic message acknowledgment before listener execution; no redelivery in case of exception thrown. "sessionAcknowledgeMode" set to "CLIENT_ACKNOWLEDGE": Automatic message acknowledgment after successful listener execution; no redelivery in case of exception thrown. "sessionAcknowledgeMode" set to "DUPS_OK_ACKNOWLEDGE": Lazy message acknowledgment during or after listener execution; potential redelivery in case of exception thrown. "sessionTransacted" set to "true": Transactional acknowledgment after successful listener execution; guaranteed redelivery in case of exception thrown.

What I want to know is that why these sources are saying different things? If all are true then How do I know how/when my message will be acknowledged?

1条回答
欢心
2楼-- · 2019-07-20 20:21

You missed out the key phrase from the abstract container javadocs...

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

The most commonly used listener container used in Spring is the DefaultMessageListenerContainer which does exhibit that behavior - it is intended for use with transactions (either local or an external transaction manager), in order to have the ability to roll back an already acknowledged message. Its listener is invoked after the receive method, so the standard JMS auto-ack has already been applied. Any JmsTemplate operations on the thread can also use the same session - and thus can be part of the transaction.

On the other hand, the SimpleMessageListenerContainer uses a traditional MessageListener and exhibits the standard JMS behavior (the listener is called from the Consumer before receive() returns; thus exceptions will stop the ack).

I suggest you read the javadocs for those concrete implementations. From the 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.

I will open up a JIRA issue for the docs on the abstract container because I can see that it might be misleading.

查看更多
登录 后发表回答