@Transactional方法中的Spring Catch JpaSystemException和回滚事务

时间:2018-10-08 13:45:01

标签: java spring error-handling transactional

我有一个用

注释的方法
@Transactional(isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)

并调用几种存储库方法。现在,当一个存储库尝试更改被该方法的另一个实例锁定且未回滚的数据库行时,sp​​ring会正确抛出

 org.springframework.orm.jpa.JpaSystemException: could not execute statement [...] Caused by: java.sql.SQLException: transaction could not be serialized and rolls back the failed transaction.

现在,我想保留所有这些行为,但还要处理异常并开始重试。这是一个代码段:

@Transactional(isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    @Lock(LockModeType.PESSIMISTIC_WRITE)
    public void messageReceived(Card card) {
        this.request = request;
        this.numberOfAttempts = reset ? 0 : this.numberOfAttempts++;
        this.reset = true;
        LOGGER.info("Message received from Queue: " + card);
        TransactionDebugUtils.transactionRequired("MessageReceivedController.messageReceived");

        try {
            [...]
            repository1.createKonto(card);
            repository2.doStuff(card);

        } catch (JpaSystemException e) {
            //This is obviously never invoked
            LOGGER.error("TRANSACTION FAILED!!!");
        } catch (Exception e) {
            LOGGER.error("Error mapping json request to data model", message, e);
        }
    }

    @ExceptionHandler(JpaSystemException.class)
    //This is also never invoked
    public void handleJpaSystemException(JpaSystemException ex) {
        this.messageReceived(this.request);
        this.reset = false;
    }

1 个答案:

答案 0 :(得分:0)

我最近遇到了这个问题。由于它是方法级别的@Transactional批注,因此在方法执行完成后才进行事务提交。 使用此批注时,应考虑2个概念

  1. 持久性上下文
  2. 数据库事务

执行messageReceived()方法后,将发生这两种情况,并且在@Transactional级别引发JPA异常,这意味着您需要从调用此方法的地方处理该异常(控制器;如果从控制器调用)。 在此link中可以找到有关@Transactional的更多信息。