【问题标题】:Unable to enforce Propagation.MANDATORY on Spring Data CRUD methods无法对 Spring Data CRUD 方法强制执行 Propagation.MANDATORY
【发布时间】:2018-05-19 05:18:51
【问题描述】:

有什么原因吗?

多年来我一直在使用 Spring 数据,但我认为我之前从未对他们的开箱即用 CRUD 方法之一进行过单元测试。

为什么下面的接口定义对 CRUD 方法的事务实现没有影响?

@Repository
@Transactional(propagation = Propagation.MANDATORY)
public interface MyRepository extends JpaRepository<MyEntity, Long> {

    Stream<MyEntity> findMyEntityByStatusEquals(Status status);
}

如果我从测试方法调用myRepository.save(new MyEntity()),而我的测试没有包含在事务中,它会成功。

但是,如果我调用 myRepository.findMyEntityByStatusEquals("MY_STATUS"),它会失败,说明需要将其包装在事务中。

我期待后一种情况,前一种情况让我感到害怕,因为我似乎无法强制它成为现有交易的一部分。

::Edit:: 结果表明将@Transactional 放在界面顶部对之前标记为@Transactional 的Spring Data CRUD 方法没有影响。当在这些接口上指定时,我一直认为它也是一个覆盖。

【问题讨论】:

  • 好像和这个other question有关
  • 这根本不是同一个问题。在提出这个问题之前,我到处寻找答案。

标签: java spring spring-data transactional propagation


【解决方案1】:

documentation here所述

默认情况下,存储库实例上的 CRUD 方法是事务性的。为了 读取操作设置了事务配置 readOnly 标志 为真,所有其他人都配置有一个普通的@Transactional,这样 应用默认事务配置。

@Transactional 将 Propagation.REQUIRED 作为其默认传播类型,因此当您调用 save 方法时,新事务就会开始。

如果您想强制 Propagation.MANDATORY 即使在 内置 CRUD 方法上,您也必须覆盖这些方法,即

@Repository
@Transactional(propagation = Propagation.MANDATORY)
public interface MyRepository extends JpaRepository<MyEntity, Long> {

    Stream<MyEntity> findMyEntityByStatusEquals(Status status);

    @Transactional(propagation = Propagation.MANDATORY)
    public <MyEntity> MyEntity save(MyEntity entity) {
      super.save(entity);
    }
}

希望对你有帮助

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2013-09-10
  • 2010-10-05
  • 2016-06-29
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
相关资源
最近更新 更多