Atomikos Forum |
|
Hi
I was trying to use the ActiveMQ, ATOMIKOS, Spring stack for xa transactions around JMS services. I followed the URL http://www.atomikos.com/Documentation/SpringIntegration#The_Advanced_Case_As_of_3_3 But still I ended up in the following issue please let me know if there is anything I am missing other than mentioned in the URL Caused by: javax.jms.JMSException: Session's XAResource has not been enlisted in a distributed transaction. at org.apache.activemq.ActiveMQXASession.doStartTransaction(ActiveMQXASession.java:109) at org.apache.activemq.ActiveMQSession.send(ActiveMQSession.java:1588) at org.apache.activemq.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:227) at org.apache.activemq.ActiveMQMessageProducerSupport.send(ActiveMQMessageProducerSupport.java:241) at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:597) at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:574) at org.springframework.jms.core.JmsTemplate$3.doInJms(JmsTemplate.java:541) at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:471) ... 6 more
The sessionTransacted is set to true
Here is the config I was using <bean id="activeMQXAConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> <bean id="AtomikosConnectionFactory" class="com.atomikos.jms.AtomikosConnectionFactoryBean" init-method="init" destroy-method="close"> <property name="uniqueResourceName" value="amq1" /> <property name="xaConnectionFactory" ref="activeMQXAConnectionFactory" /> </bean> <bean id="ConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"> <property name="targetConnectionFactory" ref="AtomikosConnectionFactory" /> </bean> <bean id="userTransactionService" class="com.atomikos.icatch.config.UserTransactionServiceImp" init-method="init" destroy-method="shutdownForce"> <constructor-arg> <!-- IMPORTANT: specify all Atomikos properties here --> <props> <prop key="com.atomikos.icatch.service">com.atomikos.icatch.standalone.UserTransactionServiceFactory </prop> </props> </constructor-arg> </bean> <bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close" depends-on="userTransactionService"> <property name="forceShutdown" value="false" /> </bean> <bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp" depends-on="userTransactionService"> <property name="transactionTimeout" value="3000" /> </bean> <bean id="JtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" depends-on="userTransactionService"> <property name="transactionManager" ref="AtomikosTransactionManager" /> <property name="userTransaction" ref="AtomikosUserTransaction" /> </bean> <bean id="AMQueue" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg value="AMQueue" /> </bean> <bean id="springJmsTopic" class="org.apache.activemq.command.ActiveMQTopic" /> <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory"> <ref bean="ConnectionFactory" /> </property> <property name="defaultDestination" ref="AMQueue"></property> </bean> <bean id="JMSServiceImpl" class="test.JMSServiceImpl"> <property name="receiver" ref="MessageReceiver" /> <property name="sender" ref="MessageSender" /> </bean> <bean id="MessageReceiver" class="test.MessageReceiver"> <property name="jmsTemplate" ref="jmsQueueTemplate" /> </bean> <bean id="MessageSender" class="test.MessageSender"> <property name="jmsTemplate" ref="jmsQueueTemplate" /> </bean> <bean id="messageListener" class="test.Listener" /> <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="transactionManager" ref="JtaTransactionManager" /> <property name="connectionFactory" ref="ConnectionFactory" /> <property name="messageListener" ref="messageListener" /> <property name="destinationName" value="AMQueue" /> <property name="concurrentConsumers" value="1" /> <property name="receiveTimeout" value="3000" /> <property name="sessionTransacted" value="true" /> </bean>
Yes you are right
I added the sesisonTransacted to the bean. Now the config is.. <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory"> <ref bean="ConnectionFactory" /> </property> <property name="defaultDestination" ref="AMQueue"></property> <property name="sessionTransacted" value="true" /> </bean> Now It resolved the old ones but now I am having the following problem. Please let me know if I am missing anything more on this config. Caused by: com.atomikos.jms.AtomikosTransactionRequiredJMSException: The JMS session you are using requires a JTA transaction context for the calling thread and none was found. Please correct your code to do one of the following: 1. start a JTA transaction if you want your JMS operations to be subject to JTA commit/rollback, or 2. increase the maxPoolSize of the AtomikosConnectionFactoryBean to avoid transaction timeout while waiting for a connection, or 3. create a non-transacted session and do session acknowledgment yourself, or 4. set localTransactionMode to true so connection-level commit/rollback are enabled. at com.atomikos.jms.AtomikosTransactionRequiredJMSException.throwAtomikosTransactionRequiredJMSException(AtomikosTransactionRequiredJMSException.java:13) at com.atomikos.jms.ConsumerProducerSupport.enlist(ConsumerProducerSupport.java:82) at com.atomikos.jms.AtomikosJmsMessageProducerProxy.send(AtomikosJmsMessageProducerProxy.java:25) at com.atomikos.jms.AtomikosJmsMessageProducerProxy.send(AtomikosJmsMessageProducerProxy.java:106) at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:597) at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:574) at org.springframework.jms.core.JmsTemplate$3.doInJms(JmsTemplate.java:541) at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:471) ... 6 more
You could try to open an explicit transaction, like so:
final TransactionTemplate transactionTemplate = new TransactionTemplate( this.transactionManager); final JmsTemplate template = this.jmsTemplate; transactionTemplate.execute(new TransactionCallback() { // the code in this method executes in a transactional context public Object doInTransaction(TransactionStatus status) { template.send(new MessageCreator() { public Message createMessage(Session session) throws JMSException { return session.createTextMessage("Hello world! From: " + Thread.currentThread().getName() + " : " + this.hashCode()); } }); return null; } }); } |