Hi
I'm struggling to get global transactions to work with datasources and JMS.
I'm using JOTM with Enhydra for the distributed datasource bits and that all works as expected.
However, I also want to publish a message onto a topic in an ActiveMQ message server on another machine within the same transaction. I'm using JmsTemplate102 in a setup pretty similar to the Ch 12 examples in the Pro Spring book.
When I add a jmsTemplate.send(...) call into the business method, the message is sent OK but doesn't enlist itself with the current transaction. (The log messages show me the datasource being enlisted and bound onto the thread - but there isn't a similar message from the JMS package).
I've tried using org.activemq.ActiveMQXAConnectionFactory as the connection factory but that gives me the following exception...
- Caused by: javax.jms.JMSException: Session's XAResource has not been enlisted in a distributed transaction.
at org.activemq.ActiveMQXASession.doStartTransaction( ActiveMQXASession.java:110)
at org.activemq.ActiveMQSession.send(ActiveMQSession. java:1355)
at org.activemq.ActiveMQMessageProducer.send(ActiveMQ MessageProducer.java:426)
at org.activemq.ActiveMQMessageProducer.send(ActiveMQ MessageProducer.java:337)
at org.activemq.ActiveMQTopicPublisher.publish(Active MQTopicPublisher.java:129)
at org.springframework.jms.core.JmsTemplate102.doSend (JmsTemplate102.java:221)
at org.springframework.jms.core.JmsTemplate.doSend(Jm sTemplate.java:762)
at org.springframework.jms.core.JmsTemplate$2.doInJms (JmsTemplate.java:739)
at org.springframework.jms.core.JmsTemplate.execute(J msTemplate.java:706)
... 44 more
I think I must be missing something but where do I tell the JMS packages about JOTM as I do with the datasources?
Here's the excerpts from my config files...
Code:... <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="userTransaction"> <ref local="jotm"/> </property> </bean> <bean id="dataSource1" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown"> <property name="driverName"> <value>oracle.jdbc.driver.OracleDriver</value> </property> <property name="transactionManager"> <ref local="jotm"/> </property> <property name="url"> <value>jdbc:oracle:thin:@foo:1521:foo</value> </property> </bean> <bean id="dataSource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown"> <property name="dataSource"> <ref local="dataSource1"/> </property> <property name="maxSize"> <value>2</value> </property> <property name="minSize"> <value>2</value> </property> <property name="user"> <value>***</value> </property> <property name="password"> <value>***</value> </property> </bean> <bean id="template" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg><ref bean="dataSource"/></constructor-arg> <property name="nativeJdbcExtractor"><bean class="org.springframework.jdbc.support.nativejdbc.XAPoolNativeJdbcExtractor"/></property> </bean>I've read about the ActiveMQ JCA container, do I need to use this in order to specify a transaction manager? The Pro Spring book doesn't mention this at all which leaves me doubtful.Code:<bean id="activeMQJndiTemplate" class="org.springframework.jndi.JndiTemplate"> <property name="environment"> <props> <prop key="java.naming.factory.initial">org.activemq.jndi.ActiveMQInitialContextFactory</prop> <prop key="brokerURL">tcp://foo:61616</prop> <prop key="topic.SupportSystem.TicketUpdateTopic">SupportSystem.TicketUpdateTopic</prop> </props> </property> </bean> <bean id="connectionFactory" class="org.activemq.ActiveMQXAConnectionFactory"> <property name="brokerURL"> <value>tcp://foo:61616</value> </property> </bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate102"> <property name="connectionFactory"> <ref local="connectionFactory"/> </property> <property name="pubSubDomain"><value>true</value></property> </bean> <bean id="ticketUpdateTopic" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiTemplate"> <ref bean="activeMQJndiTemplate"/> </property> <property name="jndiName"> <value>SupportSystem.TicketUpdateTopic</value> </property> </bean>
Thanks
Paul


Reply With Quote