I have a spring JMS listener which is listening to queue . Once the message arrives at the input queue , it does certain processing on the message and puts the messages to multiple other queues for further processing (we may call these other queues as output queues) . While its posting to other output queues, in case posting the message to one of the output queues may fail due to any reason , I want to make sure that other posts to output queues which are done prior to failure gets rolled back. Basically I want to ensure it as atomic operation . is there any annotation/configuration on the listener/container that I can use to achieve this in single transaction.?
Here Is the configuration that I am using
<jms:listener-container acknowledge="transacted" cache="session" connection-factory="jmsSecurityFactory" concurrency="1" container-type="default" container-class="abc.xyz">
<jms:listener id="listenerId" destination="inputQueue" ref="" />
</jms:listener-container>
<beans:bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<beans:property name="sessionTransacted" value="true"></beans:property>
<beans:property name="connectionFactory" ref="inCachingConnectionFactory"></beans:property>
</beans:bean>
<beans:bean id="inCachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<beans:property name="targetConnectionFactory" ref="jmsSecurityFactory" />
</beans:bean>
<beans:bean id="jmsSecurityFactory"
class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<beans:property name="targetConnectionFactory" ref="jmsConnectionFactory" />
<beans:property name="username" value=" " />
<beans:property name="password" value=" " />
</beans:bean>
<beans:bean id="jmsConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<beans:property name="hostName" value="${mq.conn.hostName}" />
<beans:property name="port" value="${mq.conn.hostPort}" />
<beans:property name="queueManager" value="${mq.conn.queueManager}" />
<beans:property name="channel" value="${mq.conn.channel}" />
<beans:property name="transportType" value="${mq.conn.transportType}" />
<beans:property name="useConnectionPooling" value="true"></beans:property>
</beans:bean>
it looks like JMS template and listener container both refer to same connection factory bean (jmsConnectionFactory)
Set acknowledge="transacted"
on the listener container; any downstream operations on the same thread, using a JmsTemplate
(configured with the same connection factory) will use the container's Session
and any failure will cause all JMS operations to roll back. The session will be committed by the container on success.