Affects Version/s: 2.5.6
Fix Version/s: None
Last commented by a User:false
When using a transaction manager with a non-durable subscription, messages are lost. Because the consumer isn't cached, Spring is opening/closing the subscription continually, in essence creating new subscriptions each time.
An overview of what's happening:
-DefaultmessageListenerContainer.initalize(): with a transaction manager, the cache level is set to CACHE_NONE
-AbstractJmsListeningContainer.doStart() - does not create shared connections based on cache level
-DefaultMessageListenerContainer.executeOngoingLoop() - controlling loop that executes while the container is active
-AbstractPollingMessageListenerContainer.doReceiveAndExecute() - attempts to receive a single message from the topic, calls the listener, and returns.
Because of the cache level, AbstractPollingMessageListenerContainer.doReceiveAndExecute() creates a new connection and new session before polling the messaging platform. After receiving a message (and calling the listener) or timing out (no message available), the session and connection are closed and the method returns. Only a single message is read in any one call.
Because the subscription ceases to exist once everything is closed, there are two possible scenarios for lost messages:
1) Additional messages are published while the listener is executing. Once the listener consumers the message, the session/connection are closed. When a non-durable subscription is closed, any messages unconsumed are lost, and therefore lost.
2) Additional messages published while the listener is not subscribed (i.e., between calls to doReceiveAndExecute()). There is no subscription and therefore the published messages just go to the bit bucket.