Spring @Transactional方法错误处理

时间:2018-09-22 21:20:44

标签: java spring exception-handling spring-data-jpa transactional

我正在使用带有@Transactional批注的事务方法。我正在尝试使用JpaRepository的save()方法将对象保存到数据库。 (由于数据库关系的限制,这将引发错误。)

现在,当我调试程序时,我发现在事务方法的末尾引发了异常,而不是在调用save方法时引发了异常。这与非事务方法的行为完全不同。

有人可以解释为什么吗?为什么在事务方法的末尾抛出异常,而不是在实际发生时抛出该异常。

我的第二个问题是,当方法为Transactional时,抛出的异常为DataViolationException,而当它为非事务性时,抛出的异常为PSQLException(使用Postgres数据库)。为什么呢?

下面是代码

@Transactional
public ResponseType methodA(UserObject userObject) {
    //save call
    jpaRepoObject.save(userObject);
    //next call will fail due to relational constraints on database
    jpaRepoObject.save(userObject); //should throw PSQLException/DataViolationException

     return new ResponseType("success"); //Error thrown after this line.
}

2 个答案:

答案 0 :(得分:0)

save doesn't immediately flush data to underlying database. First, entities are saved into first level cache, and, when time to flush come(at the end of transaction - like in your case, or when a query is issued), only then entities are saved into database.

To see behaviour which you expect, use saveAndFlush method.

答案 1 :(得分:0)

这是JPA的一项功能,称为事务后写。您的代码正在执行的所有插入和更新都将由Jpa实现进行存储,直到刷新事务为止。这使jpa实现可以对这些操作进行重新排序,以最合理的顺序进行。

刷新意味着执行到目前为止由entityManager实例存储的所有动作。您可以告诉entityManager刷新,或者一旦达到事务边界,它将自动刷新。

当您插入实体并且需要为其生成ID以便可以稍后以相同方法使用它时,显式刷新的示例。

您始终可以在事务中运行sql并在以后提交或回滚。刷新会运行sql,但不会提交。