Results 1 to 5 of 5

Thread: Help on JMS + XA Transaction!

  1. #1
    Join Date
    Feb 2008
    Posts
    17

    Post Help on JMS + XA Transaction!

    I am quite new to Spring, using standalone transaction managers. I am trying a put a message on to a queue using JMSTemplate and have it participate in a XA Transaction.

    Here are my configurations:

    Active MQ Config:

    Code:
    <bean id="xaConnectionFactory"
    		class="org.apache.activemq.ActiveMQXAConnectionFactory">
    	<property name="brokerURL"
    			value="tcp://localhost:61616" />
    </bean>
    
    <bean id="queue"
    	class="org.apache.activemq.command.ActiveMQQueue">
    	<constructor-arg value="TestQ" />
    </bean>
    Transaction Manager Config:

    Code:
    <!-- Construct a TransactionManager, needed to configure Spring	-->
    <bean id="atomikosTransactionManager"
    	class="com.atomikos.icatch.jta.UserTransactionManager"
    	init-method="init" destroy-method="close">
    	<property name="forceShutdown">
    		<value>true</value>
    	</property>
    	<property name="transactionTimeout">
    		<value>600</value>
    	</property>
    </bean>
    
    <!-- Configure a UserTransaction, needed to configure Spring -->
    <bean id="atomikosUserTransaction"
    	class="com.atomikos.icatch.jta.UserTransactionImp" />
    	
    <!-- Configure the Spring framework to use JTA transactions from the JTA provider -->
    <bean id="springTransactionManager"
    	class="org.springframework.transaction.jta.JtaTransactionManager">
    	<property name="transactionManager">
    		<ref bean="atomikosTransactionManager" />
    	</property>
    	<property name="userTransaction">
    		<ref bean="atomikosUserTransaction" />
    	</property>
    </bean>
    Code:

    Code:
    utx = (UserTransactionImp) ctx.getBean("atomikosUserTransaction");
    utx.begin();
    
    // Simulate putting message on a JMS queue
    ConnectionFactory cf = (ConnectionFactory) ctx.getBean("xaConnectionFactory");
    
    JmsTemplate jmsTemplate = new JmsTemplate();
    jmsTemplate.setConnectionFactory(cf);
    
    jmsTemplate.send(new ActiveMQQueue("queue"), new MessageCreator() {
        public Message createMessage(Session session) throws JMSException {
            return session.createTextMessage("hello queue world");
        }
    });
    & Finally the exception that is thrown:

    Code:
    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:1587)
    	at org.apache.activemq.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:226)
    	at org.apache.activemq.ActiveMQMessageProducerSupport.send(ActiveMQMessageProducerSupport.java:240)
    	at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:572)
    	at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:549)
    	at org.springframework.jms.core.JmsTemplate$3.doInJms(JmsTemplate.java:516)
    	at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:447)
    	... 24 more
    Any thoughts on the above problem?

  2. #2

    Default Configure Atomikos connection factory

    Hi,

    You seem to have forgotten an Atomikos connection factory (delegating to the Active MQ XA connection factory). The Atomikos connection factory intercepts calls to the JMS and does the XA enlist to which your error refers.

    See the Atomikos samples in the download folder for examples.

    Guy

  3. #3
    Join Date
    Feb 2008
    Posts
    17

    Unhappy Update

    Thanks for your response Guy.

    I updated the above code:

    Code:
    	<!-- Configure the JMS connector; call init to register for recovery! -->
    	<bean id="queueConnectionFactoryBean"
    		class="com.atomikos.jms.QueueConnectionFactoryBean"
    		init-method="init">
    		<property name="resourceName">
    			<value>QUEUE_BROKER</value>
    		</property>
    		<property name="xaQueueConnectionFactory">
    			<ref bean="xaConnectionFactory" />
    		</property>
    	</bean>

    Code:
    	<!-- JMS Template -->
    	<bean id="xaJmsTemplate"
    		class="org.springframework.jms.core.JmsTemplate">
    		<property name="connectionFactory"
    			ref="queueConnectionFactoryBean" />
    	</bean>
    Now, the following exception is thrown

    Code:
    javax.transaction.RollbackException: Prepare: NO vote
    	at com.atomikos.icatch.jta.TransactionImp.commit(Unknown Source)
    	at com.atomikos.icatch.jta.TransactionManagerImp.commit(Unknown Source)
    	at com.atomikos.icatch.jta.UserTransactionImp.commit(Unknown Source)
    	at com.foo.bar.xaTran.TextXA.testCommit(TestXA.java:131)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    	at java.lang.reflect.Method.invoke(Unknown Source)
    	at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
    	at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
    	at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
    	at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
    	at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
    	at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
    	at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
    	at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
    	at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
    	at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
    	at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
    	at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
    Block state after rollback : CLOSED
    java.lang.IllegalStateException: This method needs a transaction for the calling thread and none exists.
    Possible causes: either you didn't start a transaction,
    it rolledback due to timeout, or it was committed already.
    ACTIONS: You can try one of the following: 
    1. Make sure you started a transaction for the thread.
    2. Make sure you didn't terminate it yet.
    3. Increase the transaction timeout to avoid automatic rollback of long transactions;
       check http://www.atomikos.org/forums/viewtopic.php?t=1259 for how to do this.
    	at com.atomikos.icatch.jta.TransactionManagerImp.raiseNoTransaction(Unknown Source)
    	at com.atomikos.icatch.jta.TransactionManagerImp.rollback(Unknown Source)
    	at com.atomikos.icatch.jta.UserTransactionImp.rollback(Unknown Source)
    	at com.foo.bar.xaTran.TextXA.testCommit(TestXA.java:141)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    	at java.lang.reflect.Method.invoke(Unknown Source)
    	at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
    	at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
    	at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
    	at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
    	at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
    	at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
    	at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
    	at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
    	at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
    	at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
    	at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
    	at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
    My java code in the post above starts a user transaction, so this jms call is well within the scope of a transaction. I am not sure what is going wrong here... and why is it complaining that the commit is not within in a transaction. Any thoughts?

  4. #4

    Default SessionTransacted

    Please set sessionTransacted=true on the jms template.

    Guy

  5. #5
    Join Date
    Feb 2008
    Posts
    17

    Unhappy No luck

    That gave the same error:

    Code:
    	<!-- JMS Template -->
    	<bean id="xaJmsTemplate"
    		class="org.springframework.jms.core.JmsTemplate">
    		<property name="connectionFactory"
    			ref="queueConnectionFactoryBean" />
    		<property name="sessionTransacted" value="true" />
    	</bean>

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •