java - Spring @Transactional 方法错误处理

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

我正在使用使用 @Transactional 注释的事务方法。我正在尝试使用 JpaRepository 的 save() 方法将一个对象保存到数据库中。 (由于对数据库关系的约束,这将引发错误。)

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

有人可以解释为什么会这样吗?为什么在事务方法结束时抛出异常,而不是在实际应该发生的时候抛出。

我的第二个问题是,当方法是事务性时,抛出的异常是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.
}

最佳答案

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

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

显式刷新的一个例子是,如果您要插入一个实体,并且您需要为它生成一个 ID,以便稍后可以在相同的方法中使用它。

您始终可以在事务中运行 sql 并稍后提交或回滚。 Flushing 运行 sql 但不提交。

关于java - Spring @Transactional 方法错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52460985/

相关文章:

java - 从java中的字符串路径规范化斜杠

java - 为什么在关闭并重新打开对话框 fragment 后保留对象列表的值?

java - Eclipse 显示未使用的导入错误,但所有导入都是必需的

java - 需要清理 Java 8 中的 ResponseEntity 主体

仅在调试时捕获 C# 异常?

php - 显示 PHP 异常消息会带来安全风险吗?

java - 数组输入数字0-2,输出对应字母a,b,c

java - Spring启动RabbitMQ主机字符串格式

java - 如何使用jsp在Spring Boot Web应用程序中实现分页前端

Python 兼容性 : Catching exceptions