java - Spring Boot - Hibernate,异常时回滚成功保存

标签 java spring hibernate spring-boot spring-transactions

我正在使用 Spring Boot v2.1.3.RELEASE 和 Hibernate v5.3.6 构建应用程序。

之前,我问了一个关于如何跨多个服务/存储库使用 @Transactional 回滚的问题。通过将我的实体与 @OneToOne 和 @OneToMany 注释链接在一起,我得到了我需要的东西。

现在我面临一个新问题。在单个服务的函数内,我保存两个单独的实体列表。一个列表已保存,而另一个列表由于违反唯一键约束而失败。自从我测试以来,预计这会失败。

但是,我还没有弄清楚如何使用 @Transactional 注释我的 Service 或方法,以便当第二个列表保存失败时,它也会回滚第一个列表的任何成功保存。

例如:

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
protected void saveLists() {
    List<Object> list1 = this.repository.getListOne();
    List<Object> list2 = this.repository.getListTwo();

    //Loop through list one and do some manipulation
    //Loop through list two and do some manipulation

    this.repository.saveAll(list1); // this saves all successfully
    this.repository.saveAll(list2); // this has unique key exception

    // rollback both list1 and list2 changes
}

在上面的示例中,list2 抛出异常后,list1 中的数据已成功保存并出现在数据库中。

我认为,由于它们位于相同的服务和相同的方法中,使用相同的存储库,因此它们将使用相同的事务,并且 Hibernate 不会提交事务,直到它使该方法没有错误为止。

但事实似乎并非如此。由于列表一的数据正在提交并且没有回滚。

@Transactional 注释有什么我遗漏的吗? 如何使两个保存作为单个事务工作并在任一保存抛出错误时回滚两者?

最佳答案

您好@Transactional 不适用于私有(private)或 protected 方法,您的方法应该是公共(public)的。 为什么? 因为spring应该创建一个代理来处理事务划分和行为。由于不可能代理 protected 或私有(private)方法,因此您的注释将被忽略。

关于java - Spring Boot - Hibernate,异常时回滚成功保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58000528/

相关文章:

mysql - javax.resource.ResourceException : IJ000453: Unable to get managed connection

java - 避免流问题的编码指南

java - 延迟分组网络请求

mysql - Spring JPA : Multiple Aurora RDS MySQL operation is taking too much time

java - Hibernate - 有没有办法将 2 列与 1 列连接起来?

hibernate - 如何在@Embeddable 中使用@GeneratedValue 作为复合主键?

java - 渲染时 JTable 撕裂

java - 如何为 URL 创建网络图?

java - 客户端调用服务器REST API时遇到问题

java - JPA 级联更新/删除 OneToMany