通过JMS MessageListener调用时,提交失败的JPA事务

时间:2019-04-09 09:17:00

标签: spring spring-data-jpa jms spring-transactions transactional

我有一个可以正常工作的代码,但是当负载很高时会失败。找不到它的路由原因。 以下是我的用例概述

  1. 我正在从JMS队列中读取消息。
  2. 使用收到的消息调用一个REST API端点。
  3. 在我的数据库中保存从#2收到的响应。

下面是代码段

 //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);
          }
     }

当我在调试模式下运行或消息不太频繁地进入队列时,此方法工作正常。

  

但是当进入队列的消息非常快时,我得到了异常   在saveToDb方法中

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

我在这里做错什么吗?还是在多个线程同时访问它的同时,JMS和JPA事务之间有些混乱?

谢谢。

1 个答案:

答案 0 :(得分:0)

  

调用嵌套的方法/服务也标记为@Transactional时,会发生此异常。

For more details