Atomikos Forum

Strange warning messages using XA: Spring, Hibernate, MQ

I would like to ask you whether the configuration file which I posted is correct. Generally, everythig seems to work fine but I get strange atomikos warning or errors logs.

Usage scenario:
- Atomikos 3.5.4, Spring 2.5.6, Hibernate 3.2.6
- XA transaction (Oracle, and IBM WebSphere MQ)
- listenerContainer (from Spring) receives message (onMessage method) in a global transaction (XA resource: JMS_RECEIVER_XA_RMI)
- in onMessage method listenerContainer performs database operation (resource: DATABASE_XADBMS) and sends a message to a queue (resource: JMS_SENDER_XA_RMI) using JmsTemplate (from Spring)

My question are:
1.) Is my configuration valid for such a usage scenario:
2.) Do I need two XA resources for JMS sender and receiver if they connect to the same MQ broker?

I get strange warning logs:
1.) WARN: java.util.ConcurrentModificationException
atomikos connection pool 'JMS_SENDER_XA_RMI': error while trying to recycle
java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
    at java.util.AbstractList$Itr.next(Unknown Source)
    at com.atomikos.jms.AtomikosJmsConnectionProxy.isInactiveInTransaction(AtomikosJmsConnectionProxy.java:315)
    at com.atomikos.jms.AtomikosPooledJmsConnection.canBeRecycledForCallingThread(AtomikosPooledJmsConnection.java:135)
    at com.atomikos.datasource.pool.ConnectionPool.recycleConnectionIfPossible(ConnectionPool.java:77)
    at com.atomikos.datasource.pool.ConnectionPool.borrowConnection(ConnectionPool.java:107)
    at com.atomikos.jms.AtomikosConnectionFactoryBean.createConnection(AtomikosConnectionFactoryBean.java:554)
    at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:184)
    at org.springframework.jms.core.JmsTemplate.access$500(JmsTemplate.java:90)
    at org.springframework.jms.core.JmsTemplate$JmsTemplateResourceFactory.createConnection(JmsTemplate.java:1030)
    at org.springframework.jms.connection.ConnectionFactoryUtils.doGetTransactionalSession(ConnectionFactoryUtils.java:280)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:458)
    at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:539)
    at pl.pkobp.infokred.external.esb.communication.JMSClient.sendMessage(JMSClient.java:114)
    at pl.pkobp.infokred.core.worker.ExchangeWorker.confirm(ExchangeWorker.java:268)
    at pl.pkobp.infokred.core.worker.ExchangeWorker.processTask(ExchangeWorker.java:395)
    at pl.pkobp.infokred.core.worker.ExchangeWorker.run(ExchangeWorker.java:433)
    at pl.pkobp.infokred.core.worker.ExchangeScheduler.executeWorkerSynchronously(ExchangeScheduler.java:22)
    at pl.pkobp.infokred.core.worker.ExchangeAnalyzer.analyzeSubmitted(ExchangeAnalyzer.java:205)
    at pl.pkobp.infokred.core.worker.ExchangeAnalyzer.run(ExchangeAnalyzer.java:265)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)


2.) WARN: Forcing close of pending statement: oracle.jdbc.driver.OraclePreparedStatementWrapper@b8f30f


What is the cause of these warning messages???


Thanks in advance for help.
Regards,
Thomas
Tomasz Bujok Send private email
Friday, May 15, 2009
 
 
My configuration files are (in parts because there is a limit on the post length):

applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    <context:load-time-weaver />
    <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />
    <context:annotation-config />
    <context:component-scan base-package="XXX" />
    
    <bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
        <property name="uniqueResourceName"><value>DATABASE_XADBMS</value></property>
        <property name="xaDataSourceClassName" value="oracle.jdbc.xa.client.OracleXADataSource"/>        
        <property name="xaProperties">
            <props>
                <prop key="user">${db.username}</prop>
                <prop key="password">${db.password}</prop>
                <prop key="URL">${db.url}</prop>            
            </props>
        </property>
        <property name="poolSize" value="15" />
        <property name="maxPoolSize" value="30" />
        <property name="maxIdleTime" value="15" />
    </bean>


    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

        <property name="annotatedClasses">
            <list>
                <value>XXX.XXX</value>                
            </list>
        </property>

        <property name="configurationClass">
            <value>org.hibernate.cfg.AnnotationConfiguration
            </value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.Oracle9iDialect
                        </prop>
                <prop key="hibernate.query.substitutions">
                    true=1 false=0
                        </prop>

                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.format_sql">false</prop>
                <prop key="hibernate.use_sql_comments">false</prop>
                <prop key="hibernate.hbm2ddl.auto">validate</prop>
                
                <!-- http://www.atomikos.com/Documentation/JtaProperties  -->                
                <prop key="hibernate.current_session_context_class">jta</prop>                  
                <prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</prop>
                <prop key="javax.persistence.transactionType">jta</prop>

                <prop key="hibernate.transaction.auto_close_session">true</prop>
                <prop key="hibernate.connection.release_mode">auto</prop>
                <prop key="hibernate.transaction.flush_before_completion">true"</prop>
                <prop key="hibernate.cache.use_query_cache">false</prop>
                <prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
            </props>
        </property>
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
    </bean>
Tomasz Bujok Send private email
Friday, May 15, 2009
 
 
<jee:jndi-lookup id="atomikosUserTransactionService" jndi-name="java:comp/UserTransactionService"/>   
    <jee:jndi-lookup id="atomikosTransactionManager" jndi-name="java:comp/TransactionManager"/>
    <jee:jndi-lookup id="atomikosUserTransaction" jndi-name="java:comp/UserTransaction"/>

    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" depends-on="atomikosUserTransactionService">
      <property name="transactionManager" ref="atomikosTransactionManager" />
      <property name="userTransaction" ref="atomikosUserTransaction" />
      <property name="transactionSynchronizationName" value="SYNCHRONIZATION_ON_ACTUAL_TRANSACTION"/>
    </bean>    
    
    <bean id="hibernateTemplate"
        class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <bean id="mqFactory" class="com.ibm.mq.jms.MQXAQueueConnectionFactory">
        <property name="queueManager" value="${jms.broker.queue.manager}"/>
        <property name="hostName" value="${jms.broker.ip}"/>
        <property name="transportType" value="1"/>
        <property name="port" value="${jms.broker.port}"/>
        <property name="channel" value="${jms.broker.channel}"/>
    </bean>
        
    <bean id="atomikosReceiverConnectionFactoryBean" class="com.atomikos.jms.AtomikosConnectionFactoryBean">
        <property name="uniqueResourceName">
            <value>JMS_RECEIVER_XA_RMI</value>
        </property>
        <property name="xaConnectionFactory">
            <ref bean="mqFactory" />
        </property>
        <property name="poolSize" value="5" />
        <property name="maxPoolSize" value="10" />
        <property name="maxIdleTime" value="15" />        
    </bean>
    
    <bean id="atomikosSenderConnectionFactoryBean" class="com.atomikos.jms.AtomikosConnectionFactoryBean">
        <property name="uniqueResourceName">
            <value>JMS_SENDER_XA_RMI</value>
        </property>
        <property name="xaConnectionFactory">
            <ref bean="mqFactory" />
        </property>
        <property name="poolSize" value="5" />
        <property name="maxPoolSize" value="10" />
        <property name="maxIdleTime" value="15" />
    </bean>

    <bean id="requestDestination" class="com.ibm.mq.jms.MQQueue">
        <property name="baseQueueManagerName" value="${jms.broker.queue.manager}"/>
        <property name="baseQueueName" value="${jms.receiver.queue.request}"/>
    </bean>
 
    <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory">
            <ref bean="atomikosSenderConnectionFactoryBean" />
        </property>
        <property name="receiveTimeout">
            <value>20000</value>
        </property>
        <property name="sessionTransacted" value="true" />
        <property name="deliveryPersistent" value="true" />
    </bean>
        
    
    <bean id="listenerContainer"
        class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="concurrentConsumers" value="3" />
        <property name="connectionFactory" ref="atomikosReceiverConnectionFactoryBean" />
        <property name="destination" ref="requestDestination" />
        <property name="messageListener" ref="JMSHandler" />
        <property name="sessionTransacted" value="true" />
        <property name="transactionManager" ref="transactionManager" />
        <property name="autoStartup" value="false" />
        <property name="cacheLevel">
            <util:constant
                static-field="org.springframework.jms.listener.DefaultMessageListenerContainer.CACHE_NONE" />
        </property>
    </bean>
</beans>
Tomasz Bujok Send private email
Friday, May 15, 2009
 
 
Jndi.xml

<bean id="atomikosUserTransactionService" class="com.atomikos.icatch.config.UserTransactionServiceImp"
        init-method="init" destroy-method="shutdownForce">
        <constructor-arg>
            <props>
                <prop key="com.atomikos.icatch.service">
                    com.atomikos.icatch.standalone.UserTransactionServiceFactory</prop>
            </props>
        </constructor-arg>
    </bean>

    <!--
        Construct Atomikos UserTransactionManager, needed to configure Spring
    -->
    <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
        init-method="init" destroy-method="close" depends-on="atomikosUserTransactionService">
        <!--
            when close is called, should we force transactions to terminate or
            not?
        -->
        <property name="forceShutdown" value="false" />
    </bean>

    <!--
        Also use Atomikos UserTransactionImp, needed to configure Spring
    -->
    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"
        depends-on="atomikosUserTransactionService">
        <!-- timeout in seconds! -->
        <property name="transactionTimeout" value="300" />
    </bean>


    <bean id="jndi"
        class="org.apache.xbean.spring.jndi.SpringInitialContextFactory"
        factory-method="makeInitialContext">
        <property name="entries">
            <map>
                <entry key="java:comp/TransactionManager" value-ref="atomikosTransactionManager" />
                <entry key="java:comp/UserTransaction" value-ref="atomikosUserTransaction" />
                <entry key="java:comp/UserTransactionService" value-ref="atomikosUserTransactionService" />
            </map>
        </property>
    </bean>
Tomasz Bujok Send private email
Friday, May 15, 2009
 
 
Hi,

Your first warning is a bug that will be fixed in our next release.

The second warning is a safety measure: when a transaction aborts, we close all pending statements. If you want to avoid it, just make sure to close all statements when you're done.

HTH
Guy Pardon Send private email
Friday, May 15, 2009
 
 
Hi Guy,

Thank you very much for your reply and help! It is very kindof you. I have some additional questions though...

1.) I would like to ask you whether this bug "java.util.ConcurrentModificationException" can leave the XA resources in an inconsistent state? Or maybe it will only cause a safe roll-back?

2.) I have another question regarding the "WARN: Forcing close of pending statement: oracle.jdbc.driver.OraclePreparedStatementWrapper@b8f30f".
Because there are hundreds of them in my log file.

I am using Spring + Hibernate with DAO based on plain Hibernate API (http://static.springframework.org/spring/docs/2.0.x/reference/orm.html#orm-hibernate-straight), This is an example:
this.sessionFactory.getCurrentSession()              .createQuery("from ...");

I do not have a control over the statement objects that are executed. How can I explicitly close them using hibernate API???

What is exactly a pending statement? Is it a statement that was NOT executed because a rollback occurred???

3.) My third question regards the best-practices of transactional design. I use pessimistic locking in my code. The whole block of code is executed in a single transaction. I use a get method with a specified LockMode as a parameter (UPGRADE_NOWAIT). Let's assume that the required lock mode was not obtained - as a result the business logic execution was skipped. Is it better to commit such transaction or maybe rollback? I ask in the context of performance, and another transactions that are executed.

Thanks in advance for your help!

Regards,
Thomas
Tomasz Bujok Send private email
Friday, May 15, 2009
 
 
Hi,

To control when Hibernate releases (closes) connections and statements: http://docs.jboss.org/hibernate/stable/core/reference/en/html/transactions-connection-release.html

Guy
Guy Pardon Send private email
Friday, May 15, 2009
 
 
Guy,

Thank you very much for your reply.

I use "hibernate.connection.release_mode=auto" Spring documentation says that with "JTATransactionFactory" (which I also use) it returns ConnectionReleaseMode.AFTER_STATEMENT..

The behavior regarding the log message ("WARN: Forcing close of pending statement: oracle.jdbc.driver.OraclePreparedStatementWrapper@b8f30f") - I would say non-deterministic.

System works like for 10 minutes and the log does not occur - even one time. After 10 or 15 minutes (the systems performs the same tasks all the time) this log message appears - hundreds of times per second. Isn't that strange?
I mean the system pefroms the same tasks all the time - so why in the first ten minutes all the statements are closed - and after that time Atomikos TM has to close so many of them?

Regards,
Tomasz
Tomasz Bujok Send private email
Saturday, May 16, 2009
 
 
The warning occurs only if a transaction times out and aborts. Maybe the first 10 minutes there is no timeout, and after that timeouts escalate for some reason?
Guy Pardon Send private email
Saturday, May 16, 2009
 
 
Thanks for your reply. I will try to investigate the timeouts which occur.

Regards,
Tom
Tomasz Bujok Send private email
Saturday, May 16, 2009
 
 
Another strange exception:

java.lang.IllegalStateException: Wrong state for addParticipant: ABORTING in coordinator atomikos.transaction.manager.pretest0256300001
    at com.atomikos.icatch.imp.CoordinatorImp.addParticipant(CoordinatorImp.java:573)
    at com.atomikos.icatch.imp.TransactionStateHandler.addParticipant(TransactionStateHandler.java:108)
    at com.atomikos.icatch.imp.CompositeTransactionImp.addParticipant(CompositeTransactionImp.java:427)
    at com.atomikos.datasource.xa.SiblingMapper.map(SiblingMapper.java:145)
    at com.atomikos.datasource.xa.XATransactionalResource.getResourceTransaction(XATransactionalResource.java:629)
    at com.atomikos.datasource.xa.session.BranchEnlistedStateHandler.<init>(BranchEnlistedStateHandler.java:29)
    at com.atomikos.datasource.xa.session.NotInBranchStateHandler.checkEnlistBeforeUse(NotInBranchStateHandler.java:41)
    at com.atomikos.datasource.xa.session.TransactionContext.checkEnlistBeforeUse(TransactionContext.java:60)
    at com.atomikos.datasource.xa.session.SessionHandleState.notifyBeforeUse(SessionHandleState.java:151)
    at com.atomikos.jdbc.AtomikosConnectionProxy.enlist(AtomikosConnectionProxy.java:172)
    at com.atomikos.jdbc.AtomikosConnectionProxy.invoke(AtomikosConnectionProxy.java:106)
    at $Proxy27.prepareStatement(Unknown Source)
    at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:505)
    at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:423)
    at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:139)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1547)
    at org.hibernate.loader.Loader.doQuery(Loader.java:673)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
    at org.hibernate.loader.Loader.loadCollection(Loader.java:1994)
    at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
    at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
    at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:63)
    at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
    at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:454)
    at org.hibernate.engine.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:844)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:241)
    at org.hibernate.loader.Loader.doList(Loader.java:2213)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
    at org.hibernate.loader.Loader.list(Loader.java:2099)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378)
    at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
    at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
Tomasz Bujok Send private email
Monday, May 18, 2009
 
 
This is simply the transaction that has timed out by the time your application tries to do work. Nothing to worry about - should be fine.
Guy Pardon Send private email
Monday, May 18, 2009
 
 

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

Other recent topics Other recent topics