JMS Transaction Management with Spring

I am trying to manage a JMS transaction using Spring and HornetQ.
This is the code I wrote:

public void receive() { TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition()); Message msg = jmsTemplate.receive(queue); boolean success = false; if (msg != null) { try { success = handleMessage(msg); if (success) { msg.acknowledge(); // session is still open within the transaction } } catch (JMSException e) { transactionManager.rollback(status); } if (success) transactionManager.commit(status); else transactionManager.rollback(status): } } 

I am doing synchronous reading from a queue, with a timeout of 0, since I do not want to block reading. Because of this, I have to check if something was really received.

This is an excerpt from my applicationContext.xml :

 <bean id="inVMConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:/ConnectionFactory</value> </property> </bean> <bean id="cachedConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"> <property name="targetConnectionFactory" ref="inVMConnectionFactory" /> </bean> <bean id="producer" class="it.ubiquity.gestoreprofilazione.onweb.OnWebProducer" scope="singleton"> <property name="queue" ref="retryQueue" /> <property name="connectionFactory" ref="cachedConnectionFactory" /> </bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="cachedConnectionFactory" /> <property name="sessionTransacted" value="true" /> <property name="sessionAcknowledgeMode" value="#{T(javax.jms.Session).CLIENT_ACKNOWLEDGE}" /> <property name="pubSubDomain" value="false" /> <property name="receiveTimeout" value="# {T(org.springframework.jms.core.JmsTemplate).RECEIVE_TIMEOUT_NO_WAIT}" /> </bean> <bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager"> <property name="connectionFactory" ref="cachedConnectionFactory" /> </bean> <bean id="consumer" class="it.ubiquity.gestoreprofilazione.onweb.OnWebConsumer" scope="singleton"> <property name="queue" ref="retryQueue" /> <property name="jmsTemplate" ref="jmsTemplate" /> <property name="transactionManager" ref="jmsTransactionManager" /> </bean> 

My problem is rather strange: the first time I get a message, handleMessage fails, so I roll back the transaction. Then nothing else happens. If I check using the JMX console, I see there is one message in the queue. Now, if I restart JBoss, the messages will be received again and again, as expected.
There may be something wrong with my configuration, but why does it work after a reboot?

  • HornetQ 2.2.10
  • JBoss 5.1.0
  • Spring 3.1.2

UPDATE
With debugging enabled, I see the first time:

DEBUG [org.springframework.jms.connection.JmsTransactionManager] (baseScheduler-1) Create a new transaction named [null]: PROPAGATION_REQUIRED, ISOLATION_DEFAULT

and after the first rollback with subsequent reception and rollback, I see:

DEBUG [org.springframework.jms.connection.JmsTransactionManager] (baseScheduler-1) Participation in an existing transaction

Instead, after restarting JBoss, I read that the transaction is actually rollback:

DEBUG [org.springframework.jms.connection.JmsTransactionManager] (baseScheduler-1) Initiation of a transactional rollback 2012-11-05 09:54:14,436 DEBUG [Org.springframework.jms.connection.JmsTransactionManager] (baseScheduler-1) JMS transaction rollback in session

So, why the rollback does not happen the first time, and as soon as I restart the server, it happens all the time? What am I doing wrong?

+4
source share
1 answer

Well, finally, I managed to understand my mistake :) In the external, if otherwise, I must have a transaction completed . This is why the mechanism works after restarting JBoss: the transaction does not hang.

+4
source

Source: https://habr.com/ru/post/1443271/


All Articles