Atomikos Forum |
|
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
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>
<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>
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>
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
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,
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
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) |