0

I have following configuration in the application that works perfectly fine with queues and redelivers the messages when a RuntimeException occurs with transaction rollback as expected.

But the same configuration fails to redeliver message with topics and emits following warning message:

WARN  DefaultMessageListenerContainer - Setup of JMS message listener invoker failed for destination 'XXX_TOPIC' - trying to recover. Cause: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException: One or more resources refused to commit (possibly because of a timeout in the resource - see the log for details). This transaction has been rolled back instead.

Configuration:

<bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory">
    <property name="brokerURL" value="tcp://localhost:61616"/>
    <!-- <property name="sendTimeout" value="1000"/> -->
    <property name="redeliveryPolicy" ref="redeliveryPolicy"/>
</bean>

<!-- Atomikos Connection Factory Wrapper For Gobal Tx -->
<bean id="queueConnectionFactoryBean" class="com.atomikos.jms.AtomikosConnectionFactoryBean">
    <property name="uniqueResourceName" value="amq1" />
    <property name="xaConnectionFactory" ref="amqConnectionFactory" />
</bean>

<bean id="jmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory">
        <ref bean="queueConnectionFactoryBean"/>
    </property>
    <property name="sessionCacheSize" value="20"/>
    <property name="cacheConsumers" value="false"/>
</bean>

<bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager">
        <bean class="com.atomikos.icatch.jta.UserTransactionManager"
                init-method="init"
                destroy-method="close">
            <property name="forceShutdown" value="false" />
        </bean>
    </property>
    <property name="userTransaction">
        <bean class="com.atomikos.icatch.jta.UserTransactionImp">
            <property name="transactionTimeout" value="300" />
        </bean>
    </property>
</bean> 

<!-- Topic configuration -->
<bean id="messageListener1" class="com.x.y.impl.JmsMessageListener"></bean>

<bean id="container1" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
    <property name="destinationName" value="XXX_TOPIC"/>
    <property name="messageListener" ref="messageListener1" />
    <property name="pubSubDomain" value="true" />
    <property name="transactionManager" ref="jtaTransactionManager" />
    <property name="concurrency" value="1" />
    <property name="receiveTimeout" value="3000" />

    <!-- For local session and Atomikos-->
    <property name="sessionTransacted" value="true"/>
</bean>

<!-- Bean configuration -->
<bean id="messageListener2" class="com.x.y.impl.JmsMessageListener"></bean>

<bean id="container2" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
    <property name="destinationName" value="XXX_QUEUE"/>
    <property name="messageListener" ref="messageListener2" />
    <property name="pubSubDomain" value="false" />
    <property name="transactionManager" ref="jtaTransactionManager" />
    <property name="concurrency" value="1" />

    <!-- For local session and Atomikos-->
    <property name="sessionTransacted" value="true"/>
</bean>

The Spring version used is 3.1, ActiveMQ 5.14, Atomikos 4.0.6. Please let me know if i missed any configuration for topic DMLC.

Justin Bertram
  • 29,372
  • 4
  • 21
  • 43
Sonu
  • 1
  • 1
  • What role is the `RuntimeException` playing here? Are you throwing it from `onMessage` to trigger redelivery? – Justin Bertram Mar 11 '19 at 16:53
  • Yes, on a specific application exception a RuntimeException is thrown, this is coded common for both Queue and Topic. – Sonu Mar 11 '19 at 17:01
  • For what it's worth, the JMS 1.1 specification states, "It is possible for a listener to throw a RuntimeException; however, *this is considered a client programming error*" (emphasis mine). I could encourage you to handle your exceptions with a try/catch, log the necessary details, and rollback the transaction through the proper API. – Justin Bertram Mar 11 '19 at 17:13
  • OK, will try that but i am not clear why above is working fine for queue but not for Topic. In case of RuntimeException container should take care of rollback and redelivery. – Sonu Mar 12 '19 at 05:01
  • I don't necessarily think that throwing the `RuntimeException` is the cause of your problem, but it's still worth fixing regardless especially since it *could* be related. – Justin Bertram Mar 12 '19 at 13:09

0 Answers0