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:
This is how my configuration looks like: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 the implementation of my JmsGatewaySupport: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>
Also, I have tried using both JtaTransactionManager and JmsTransactionManager.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"); } }
Any advice?
Cheers,
yc


Reply With Quote