Spring 引导 - 休眠,异常时回滚成功保存

Spring Boot - Hibernate, Rollback successful save upon exception

我正在使用 Spring Boot v2.1.3.RELEASE 和 Hibernate v5.3.6.

构建应用程序

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

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

但是,我还没有想出如何用@Transactional 注释我的服务或方法,这样当第二个列表保存失败时,它也会回滚第一个列表的任何成功保存。

例如:

@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
}

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

我认为,由于它们在相同的服务和相同的方法中,使用相同的存储库,因此它们将使用相同的事务,并且 Hibernate 在没有错误地离开此方法之前不会提交事务.

但似乎并非如此。由于列表一的数据正在提交而不是回滚。

关于@Transactional 注释我是否遗漏了什么? 我怎样才能使两个保存作为一个事务工作,并在任何一个保存抛出错误时回滚两者?

你只需要用 @Transactional 注释在控制器中调用的服务方法而不是这个方法。 或者您可以使用 @Transactional

注释服务 class

你好@Transactional 不适用于私有或受保护的方法,你的方法应该是public。 为什么? 因为 spring 应该创建一个代理来处理事务划分和行为。由于无法代理受保护或私有方法,因此您的注释只是忽略 .