-
Atomikos and JmsTemplate
Hello everybody,
I'm a spring newbie and I'm trying to get some relatively simple stuff to work. My task is to read n messages from a JMS queue and persist them to a database all in a single transaction. I'm using Atomikos as the transaction manager and I was trying to have Spring tie everything together. So here's my configuration file:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- Configure the JMS connector; call init to register for recovery! -->
<bean id="ConnectionFactory" class="com.atomikos.jms.AtomikosConnectionFactoryBean"
init-method="init" destroy-method="close">
<property name="uniqueResourceName" value="ADCqueue" />
<property name="xaConnectionFactory">
<bean class="com.tibco.tibjms.TibjmsXAQueueConnectionFactory">
<property name="serverUrl" value="tcp://10.254.166.140:7222" />
<property name="userName" value="analyticsdatacloud" />
<property name="userPassword" value="an@lytic$datacloud" />
</bean>
</property>
<property name="localTransactionMode" value="false" />
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref bean="ConnectionFactory" />
</property>
<property name="defaultDestination">
<bean class="com.tibco.tibjms.TibjmsQueue">
<property name="address" value="TR.OCP01QD.ANALYTICS.DATA.CLOUD.1" />
</bean>
</property>
<property name="receiveTimeout" value="60000" />
<property name="sessionTransacted" value="true" />
</bean>
<!-- Configure the database -->
<bean id="dataSource" class="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean"
init-method="init" destroy-method="close">
<property name="uniqueResourceName" value="DataSource" />
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="user" value="postgres" />
<property name="password" value="postgres" />
<property name="url" value="jdbc:postgresql://localhost:5432/lrg" />
<property name="poolSize" value="2" />
</bean>
<!-- Configure the Spring framework to use JTA transactions from Atomikos -->
<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">
<!-- when close is called, should we force transactions to terminate
or not? -->
<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>
<tx:annotation-driven transaction-manager="JtaTransactionManager" />
</beans>
Unfortunately this doesn't work for me. After I obtain my jmsTemplate bean and call the receive method, I get an error:
Code:
2013-02-19 15:27:06,650 [main] WARN com.atomikos.jms.ConsumerProducerSupport - atomikos MessageConsumer proxy for QueueReceiver[queue=TR.OCP01QD.ANALYTICS.DATA.CLOUD.1]: 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.
2013-02-19 15:27:06,650 [main] WARN 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.
2013-02-19 15:27:06,651 [main] WARN com.atomikos.jms.AtomikosJMSException - Error in proxy
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:40)
at com.atomikos.jms.ConsumerProducerSupport.enlist(ConsumerProducerSupport.java:112)
at com.atomikos.jms.AtomikosJmsMessageConsumerProxy.receive(AtomikosJmsMessageConsumerProxy.java:72)
at com.atomikos.jms.AtomikosJmsMessageConsumerProxy.receive(AtomikosJmsMessageConsumerProxy.java:139)
at org.springframework.jms.core.JmsTemplate.doReceive(JmsTemplate.java:774)
at org.springframework.jms.core.JmsTemplate.doReceive(JmsTemplate.java:741)
at org.springframework.jms.core.JmsTemplate.doReceive(JmsTemplate.java:722)
at org.springframework.jms.core.JmsTemplate$9.doInJms(JmsTemplate.java:697)
at org.springframework.jms.core.JmsTemplate$9.doInJms(JmsTemplate.java:695)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:466)
at org.springframework.jms.core.JmsTemplate.receiveSelected(JmsTemplate.java:695)
at org.springframework.jms.core.JmsTemplate.receive(JmsTemplate.java:677)
at org.springframework.jms.core.JmsTemplate.receive(JmsTemplate.java:669)
I'm sure this is a rookie mistake, can anyone point that out for me?
Thanks!
Giovanni
-
Try using XA datasource.
Also refer http://www.javaworld.com/javaworld/j...xa.html?page=5 for Atomikos configuration.
Vaijesh
-
I actually figured out what was wrong: I didn't create my DAO object using Spring. This is necessary because I have @Transactional annotations in it!
Thanks