简体   繁体   中英

Database rollback not happening when using @JmsListener to listen to messages from IBM MQ

I am using the @JmsListener annotation from Spring JMS to consume messages from an IBM MQ queue, but when an exception occurs the database updates are not being rolled back. The JMS listener is only rolling back the MQ messages, ie dequeuing the message and putting it back in the queue. How can I ensure that the database updates are also rolled back in this scenario?

Sample code:

@Service
@Transactional
@JMSListener(containerFactory="jmsListenerContainerFactory",destination="ibm.mq.request")
public class TestListener {

   public void receive message(String message) {
        
       1:  // convert message to object apply business logic

       2:  // insert into order_table;

       3:  // convert object back to string and put it into response queue
       4:  jmsTemplate.convertAndSend("ibm.mq.response",message);
    }
}

When the listener starts, picks a message from MQ, converts it to an Object , applies some logic, and persists in the database.

Issue: When an exception occurs at step 4, Listener picks up the same message (which indicates the message is still in the MQ) but the database insert did not roll back.

Can someone help me how to roll back database insert/updates?

JMS config file:

    @Bean
    public JmsTransactionManager jmsTransactionManager(MQConnectionFactory connectionFactory){
       return new JmsTransactionManager(connectionFactory);
    }

    @Bean
    public JmsTemplate jmsTemplate(MQConnectionFactory connectionFactory){
       JmsTemplate jmsTemplate = new JmsTemplate (connectionFactory);
       jmsTemplate.setSessionTransacted(true);
       return jmsTemplate;
    }

The JmsTransactionManager is only capable of managing transactions on the connections that are issued by the connection factory that it contains. In order to have synchronized transactions between JMS and your database, you will need to have a JTA transaction manager configured. This is best done by having the JTA transaction manager being the PlatformTransactionManager .

With synchronized transactions, you will have DUPS-OK functionality. The JMS message listener will start a transaction in a new transaction context. The JPA database persistence will then join the existing JTA transaction and there will be two transactions in the transaction context.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM