Announcement Announcement Module
Collapse
No announcement yet.
JMS and Transaction Management not working as expected Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • JMS and Transaction Management not working as expected

    Hi all,

    I am kind of new to JMS and I am trying to set up transaction management after reading a few articles from OnJava and JavaWorld. Pardon me if I'm having some terribly wrong concept about JMS and its TX.

    I am trying to do the following (they are separate tests):

    1. Send a message to a JMS queue; Throw exception at the end of execution to simulate a problem.
    2. Read a message from a JMS queue; Throw exception at the end for the same purpose.

    I am expecting:

    1. The message will not be delivered to the queue since there is a rollback.
    2. The message will not be consumed/will be restored due to the rollback.

    However, I couldn't really realize my expectation -- message is still delivered, message is still consumed. From the debug log, I'm seeing:

    Code:
    20:05:47.546 DEBUG [org.apache.activemq.ActiveMQSession:send] ID:nemesis-2858-1192017947250-0:1:1 sending message: ActiveMQTextMessage {commandId = 0, responseRequired = false, messageId = ID:nemesis-2858-1192017947250-0:1:1:1:1, originalDestination = null, originalTransactionId = null, producerId = ID:nemesis-2858-1192017947250-0:1:1:1, destination = queue://foobar, transactionId = TX:ID:nemesis-2858-1192017947250-0:1:1, expiration = 0, timestamp = 1192017947531, arrival = 0, brokerInTime = 0, brokerOutTime = 0, correlationId = null, replyTo = null, persistent = true, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = null, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false, text = foo: Wed Oct 10 20:05:47 SGT 2007}
    20:05:47.546 DEBUG [org.apache.activemq.ActiveMQSession:commit] ID:nemesis-2858-1192017947250-0:1:1 Transaction Commit
    20:05:47.562 DEBUG [org.apache.activemq.transport.tcp.TcpTransport:doStop] Stopping transport tcp://localhost/127.0.0.1:61616
    20:05:47.562 DEBUG [org.springframework.transaction.interceptor.TransactionAspectSupport:completeTransactionAfterThrowing] Completing transaction for [foo.main.tx.TestSpringTx$TestJmsGateway.insertOneMessage] after exception: java.lang.RuntimeException: tx is going to fail :D
    20:05:47.562 DEBUG [org.springframework.transaction.interceptor.RuleBasedTransactionAttribute:rollbackOn] Applying rules to determine whether transaction should rollback on java.lang.RuntimeException: tx is going to fail :D
    20:05:47.562 DEBUG [org.springframework.transaction.interceptor.RuleBasedTransactionAttribute:rollbackOn] Winning rollback rule is: RollbackRuleAttribute with pattern [Exception]
    20:05:47.562 DEBUG [org.apache.activemq.ActiveMQSession:rollback] ID:nemesis-2858-1192017947250-0:0:1 Transaction Rollback
    20:05:47.562 DEBUG [org.springframework.transaction.support.TransactionSynchronizationManager:unbindResource] Removed value [org.springframework.jms.connection.JmsResourceHolder@1267649] for key [org.apache.activemq.ActiveMQConnectionFactory@149d886] from thread [main]
    20:05:47.578 DEBUG [org.apache.activemq.transport.tcp.TcpTransport:doStop] Stopping transport tcp://localhost/127.0.0.1:61616
    This is how my configuration looks like:

    Code:
    	<bean id="innerConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    		<property name="brokerURL" value="tcp://localhost:61616" />
    	</bean>
    
    	<bean id="connectionFactory" class="org.springframework.jms.connection.TransactionAwareConnectionFactoryProxy">
    		<property name="targetConnectionFactory" ref="innerConnectionFactory"></property>
    	</bean>
    
    
    	<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean" />
    
    	<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    		<property name="transactionManager">
    			<ref local="jotm" />
    		</property>
    		<property name="userTransaction">
    			<ref local="jotm" />
    		</property>
    	</bean>
    	
    	<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
    		<property name="connectionFactory" ref="connectionFactory"/>
    	</bean>
    
    	<bean id="testGatewayTarget1" class="foo.main.tx.TestSpringTx$TestJmsGateway">
    		<property name="connectionFactory" ref="connectionFactory" />
    	</bean>
    
    	<bean id="testGateway1" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
    		scope="prototype">
    		<property name="transactionManager" ref="jmsTransactionManager" />
    
    		<property name="target" ref="testGatewayTarget1" />
    		<property name="transactionAttributes">
    			<props>
    				<prop key="*">PROPAGATION_REQUIRED,-Exception</prop>
    			</props>
    		</property>
    		<property name="proxyTargetClass" value="true" />
    	</bean>
    This is the implementation of my JmsGatewaySupport:

    Code:
    public static class TestJmsGateway extends JmsGatewaySupport{
    		
    		public Message getOneMessage()	
    			throws Exception{
    			
    			LOGGER.debug("Invoking getOneMessage..");
    			
    			JmsTemplate jmsTemplate = this.getJmsTemplate();
    			jmsTemplate.setSessionTransacted(true);
    			jmsTemplate.setSessionAcknowledgeMode(Session.SESSION_TRANSACTED);
    			Message message= jmsTemplate.receive("foobar");
    			
    			LOGGER.debug("Got message out: " + message);
    
    			if(THROW_EXCEPTION) throw new RuntimeException("tx is going to fail :D");
    			
    			return message;
    		}
    		
    		public void insertOneMessage()
    			throws Exception{
    
    			JmsTemplate jmsTemplate = this.getJmsTemplate();
    			jmsTemplate.setSessionTransacted(true);
    			jmsTemplate.setDefaultDestinationName("foobar");
    			jmsTemplate.send(					
    					new MessageCreator(){
    						public Message createMessage(Session session) throws JMSException{
    							return session.createTextMessage("foo: " + new Date().toString());
    						}
    					}					
    				);
    			if(THROW_EXCEPTION) throw new RuntimeException("tx is going to fail :D");
    			LOGGER.debug("Sent");
    		}
    	}
    Also, I have tried using both JtaTransactionManager and JmsTransactionManager.

    Any advice?

    Cheers,
    yc

  • #2
    Does anyone have anything to share on this? Or a link of a decent document?

    Cheers.

    Comment


    • #3
      Hello,

      where is the transaction started inside your application ?
      Is the calling method itself transactional ? (i.e. Marked through @Transaction annotation)

      rgds
      agim

      Comment

      Working...
      X