Search code examples
springspring-data-jpajmsspring-transactionstransactional

Commit failure JPA transaction when invoked through JMS MessageListener


I have a code which works fine but fails when the load is high. Not able to find the route cause of it. Following is overview of my use case

  1. I am reading message from JMS queue.
  2. Calling one REST API endpoint with the message received.
  3. Saving back the response received from #2 in my database.

Below is code snippet

 //Message Listener class which reads the messages from JMS Queue
 public class MyListener implements MessageListener {
        @Autowired
        MyDao myDao;

        @Override
        public void onMessage(Message message) {
             MyResponse resp = callRest(message);
             myDao.saveToDb(resp);
       }
    }

    //DAO class which updates my entity   
    @Component
    public class MyDao {
          @Autowired
          EntityManager entityManager;

          @Transactional
           public boolean saveToDb(MyResponse resp) {
             Query query = entityManager.createQuery("from MyTable mt where mt.id=:id");
             query.setParameter("id", myResp.getId());
             MyTable myTab = (MyTable) query.getSingleResult();
             myTab.setProcessFlag(true);
             entityManager.merge(myTab);
          }
     }

This works fine when I run in debug mode or when the messages are coming in queue not so frequently.

But when messages coming in queue are very fast then I get exception in saveToDb method as

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction

Am I doing anything wrong here or if there is some confusion between JMS and JPA transactions while multiple threads are accessing it simultaneously ?

Thanks in advance.


Solution

  • This exception occurs when you invoke nested methods/services also marked as @Transactional.

    For more details