Skip to content

Commit 95f7180

Browse files
committed
Explicit documentation notes on transacted sessions vs AUTO_ACKNOWLEDGE
Issue: SPR-16487
1 parent 3b810f3 commit 95f7180

File tree

3 files changed

+27
-11
lines changed

3 files changed

+27
-11
lines changed

spring-jms/src/main/java/org/springframework/jms/annotation/EnableJms.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@
4141
* DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
4242
* factory.setConnectionFactory(connectionFactory());
4343
* factory.setDestinationResolver(destinationResolver());
44+
* factory.setSessionTransacted(true);
4445
* factory.setConcurrency("5");
4546
* return factory;
4647
* }

spring-jms/src/main/java/org/springframework/jms/annotation/JmsListener.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,6 +33,12 @@
3333
* assumed to be available with a bean name of {@code jmsListenerContainerFactory}
3434
* unless an explicit default has been provided through configuration.
3535
*
36+
* <p><b>Consider setting up a custom
37+
* {@link org.springframework.jms.config.DefaultJmsListenerContainerFactory} bean.</b>
38+
* For production purposes, you'll typically fine-tune timeouts and recovery settings.
39+
* Most importantly, the default 'AUTO_ACKNOWLEDGE' mode does not provide reliability
40+
* guarantees, so make sure to use transacted sessions in case of reliability needs.
41+
*
3642
* <p>Processing of {@code @JmsListener} annotations is performed by registering a
3743
* {@link JmsListenerAnnotationBeanPostProcessor}. This can be done manually or,
3844
* more conveniently, through the {@code <jms:annotation-driven/>} element or

src/docs/asciidoc/integration.adoc

+18-9
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,13 @@ the message getting redelivered. Alternatively, consider using 'CLIENT_ACKNOWLED
17971797
which provides redelivery in case of an exception as well but does not use transacted
17981798
Sessions and therefore does not include any other Session operations (such as sending
17991799
response messages) in the transaction protocol.
1800+
1801+
**The default 'AUTO_ACKNOWLEDGE' mode does not provide proper reliability guarantees.**
1802+
Messages may get lost when listener execution fails (since the provider will automatically
1803+
acknowledge each message after listener invocation, with no exceptions to be propagated to
1804+
the provider) or when the listener container shuts down (this may be configured through
1805+
the 'acceptMessagesWhileStopping' flag). Make sure to use transacted sessions in case of
1806+
reliability needs, e.g. for reliable queue handling and durable topic subscriptions.
18001807
====
18011808

18021809
[[jms-mdp-default]]
@@ -1834,6 +1841,13 @@ alternative: wrapping your entire processing with an XA transaction (through con
18341841
your `DefaultMessageListenerContainer` with an `JtaTransactionManager`), covering the
18351842
reception of the JMS message as well as the execution of the business logic in your
18361843
message listener (including database operations etc).
1844+
1845+
**The default 'AUTO_ACKNOWLEDGE' mode does not provide proper reliability guarantees.**
1846+
Messages may get lost when listener execution fails (since the provider will automatically
1847+
acknowledge each message before listener invocation) or when the listener container shuts
1848+
down (this may be configured through the 'acceptMessagesWhileStopping' flag). Make sure
1849+
to use transacted sessions in case of reliability needs, e.g. for reliable queue handling
1850+
and durable topic subscriptions.
18371851
====
18381852

18391853

@@ -2065,7 +2079,6 @@ Below is a simple implementation of an MDP:
20652079
throw new IllegalArgumentException("Message must be of type TextMessage");
20662080
}
20672081
}
2068-
20692082
}
20702083
----
20712084

@@ -2108,7 +2121,6 @@ handling method with access to the JMS `Session` from which the `Message` was re
21082121
public interface SessionAwareMessageListener {
21092122
21102123
void onMessage(Message message, Session session) throws JMSException;
2111-
21122124
}
21132125
----
21142126

@@ -2153,7 +2165,6 @@ various `Message` types that they can receive and handle.
21532165
void handleMessage(byte[] message);
21542166
21552167
void handleMessage(Serializable message);
2156-
21572168
}
21582169
----
21592170

@@ -2200,7 +2211,6 @@ also how the `'receive(..)'` method is strongly typed to receive and respond onl
22002211
public interface TextMessageDelegate {
22012212
22022213
void receive(TextMessage message);
2203-
22042214
}
22052215
----
22062216

@@ -2242,7 +2252,6 @@ non-void value. Consider the interface and class:
22422252
22432253
// notice the return type...
22442254
String receive(TextMessage message);
2245-
22462255
}
22472256
----
22482257

@@ -2469,10 +2478,10 @@ your `@Configuration` classes.
24692478
24702479
@Bean
24712480
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
2472-
DefaultJmsListenerContainerFactory factory =
2473-
new DefaultJmsListenerContainerFactory();
2481+
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
24742482
factory.setConnectionFactory(connectionFactory());
24752483
factory.setDestinationResolver(destinationResolver());
2484+
factory.setSessionTransacted(true);
24762485
factory.setConcurrency("3-10");
24772486
return factory;
24782487
}
@@ -2501,6 +2510,7 @@ element.
25012510
class="org.springframework.jms.config.DefaultJmsListenerContainerFactory">
25022511
<property name="connectionFactory" ref="connectionFactory"/>
25032512
<property name="destinationResolver" ref="destinationResolver"/>
2513+
<property name="sessionTransacted" value="true"/>
25042514
<property name="concurrency" value="3-10"/>
25052515
</bean>
25062516
----
@@ -2696,8 +2706,7 @@ the time to live, you can configure the `JmsListenerContainerFactory` accordingl
26962706
26972707
@Bean
26982708
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
2699-
DefaultJmsListenerContainerFactory factory =
2700-
new DefaultJmsListenerContainerFactory();
2709+
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
27012710
factory.setConnectionFactory(connectionFactory());
27022711
QosSettings replyQosSettings = new ReplyQosSettings();
27032712
replyQosSettings.setPriority(2);

0 commit comments

Comments
 (0)