Atomikos Forum

MQ messages lost when Tomcat abruptly shutdown

Hi Guys,

We are using Atomikos 3.6 as with Spring 2 and JPA (Hibernate 3.3). We have an interface with other systems where via IBM MQ 5.

There are some memory issues with our application and sometimes need to restart our Tomcat. When the server does not respond to the stop command we do a force stop. If a message is received during that time, the message is lost and it is not saved in the database either.

As far as I understand, the transaction manager commits both at the database level and MQ level or rolls back. Then in this case, the messages should not have been committed at the MQ level and must be available when the server starts up.

Is there something that I missed in my understanding or configuration ?

Thanks,
Midhun
Midhun Agnihotram Send private email
Wednesday, December 21, 2011
 
 
Hi Midhun,

the JMS transaction configuration for Spring has some challenges. It is easily possible start in transaction mode but reading the queue is auto committed. This would lead to your problem with missing messages and produce memory leaks.

This memory leak can be checked with jmap/jhat from jdk. If you spot lots of MQQueueReceiver/Sender and Atomikos classes, your configuration needs to be improved.

But without your Spring xml files I can only guess.

Regards,
Rainer
Rainer Wallscheid Send private email
Wednesday, December 21, 2011
 
 
Hi Rainer,

Thank you for the response. I checked the Spring documentation which says that we need to configure a JtaTransactionManager for XA Transactions. Our configuration has been setup for XA transactions. The configurations are as below :

Spring Listner :


    <!-- Abstract Message Listener Container -->
    <bean id="abstractMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer" abstract="true">
        <property name="connectionFactory" ref="jmsConnectionFactory" />
        <property name="transactionManager" ref="transactionManager" />
        <property name="sessionTransacted" value="true" />
    </bean>

    <bean id="InQueueMessageListenerContainer" parent="abstractMessageListenerContainer">
        <property name="destination" ref="InQueue" />
        <property name="messageListener">
            <bean class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
                <constructor-arg index="0">
                    <bean class="com.xxxxxx.cccccc.vvvvvv.tttttt.ffffff.jjjjjj.impl.QueueProcessor" />
                </constructor-arg>
            </bean>
        </property>
    </bean>

JMS Connection Factory :

    <bean id="jmsConnectionFactory"
        class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter" depends-on="sysPropsLoader">
        <property name="targetConnectionFactory">
            <bean class="com.atomikos.jms.QueueConnectionFactoryBean"
                init-method="init">
                <property name="xaQueueConnectionFactory">
                    <bean class="com.ibm.mq.jms.MQXAQueueConnectionFactory">
                        <property name="transportType" value="${jms.transportType}" />
                        <property name="hostName" value="${jms.hostName}" />
                        <property name="port" value="${jms.port}" />
                        <property name="channel" value="${jms.channel}" />
                        <property name="SSLCipherSuite" value="${jms.ssl.cipherSuite}" />
                    </bean>
                </property>
                <property name="resourceName" value="${jms.queue.manager}_MQSeries_XA_RMI" />
            </bean>
        </property>
        <property name="username" value=" " />
        <property name="password" value=" " />
    </bean>

Transaction Manager Config :

    <bean id="atomikosTransactionManager"
        class="com.atomikos.icatch.jta.UserTransactionManager"
        init-method="init" destroy-method="close">
        <property name="forceShutdown" value="true" />
    </bean>

    <bean id="atomikosUserTransaction"
        class="com.atomikos.icatch.jta.UserTransactionImp">
        <property name="transactionTimeout" value="${transaction.timeout}" />
    </bean>

    <bean id="transactionManager"
        class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager"
            ref="atomikosTransactionManager" />
        <property name="userTransaction" ref="atomikosUserTransaction" />
    </bean>    


Thanks,
Midhun
Midhun Agnihotram Send private email
Tuesday, December 27, 2011
 
 
Hi Midhun,

the Spring documentation refers to a J2EE environment. But Spring/Tomcat/Atomikos is no J2EE environment. Therefore you have to add properties to the spring configuration to get the expected workflow.

I your case sessionAcknoledgeMode has to be added to prevent auto commit on read which is the default setting of Spring.

    <bean id="abstractMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer" abstract="true">
        <property name="connectionFactory" ref="jmsConnectionFactory" />
        <property name="transactionManager" ref="transactionManager" />
        <property name="sessionTransacted" value="true" />
        <property name="sessionAcknowledgeMode" value="0" />
    </bean>
Rainer Wallscheid Send private email
Thursday, December 29, 2011
 
 
Hi Rainer,

Thank you. I read about sessionAcknowledgeMode and I think a value of 2 (CLIENT_ACKNOWLEDGE) is what I am looking for.

References :

http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/jms/listener/AbstractMessageListenerContainer.html

http://docs.oracle.com/javaee/1.4/api/constant-values.html#javax.jms.Session.CLIENT_ACKNOWLEDGE


Let me know if I am on the wrong track.

Thanks,
Midhun
Midhun Agnihotram Send private email
Friday, December 30, 2011
 
 
Hi Midhun,

sessionAcknowledgeMode should only be set if you do not use transactions. So you should set either sessionAcknowledgeMode or sessionTransacted as stated by Spring's documentation.

A "hack" is needed in your environment to work. sessionTransacted has to be set to true AND sessionAcknowledgeMode to 0.

A have not compared Spring and Atomikos to the spec's. Therefore I can not say if it is a bug or a feature. But this hack works for me with MQSeries or ActiveMQ as JMS provider.

Cheers,
Rainer
Rainer Wallscheid Send private email
Saturday, December 31, 2011
 
 
Thanks Rainer. I will definitely try this hack and let you know whether I am able to retain those messages.

Thank you for the help !

Thanks,
Midhun
Midhun Agnihotram Send private email
Tuesday, January 10, 2012
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics