这有什么原因吗?
我多年来一直在使用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方法没有影响。我总是认为在这些接口上指定时它也是一个覆盖。
答案 0 :(得分:2)
默认情况下,存储库实例上的CRUD方法是事务性的。对于 读取操作事务配置readOnly标志已设置 为true,所有其他人都配置了一个简单的@Transactional,以便 默认事务配置适用。
@Transactional将Propagation.REQUIRED作为其默认传播类型,因此当您调用save
方法时,新事务才会开始。
如果你想在 buily-in CRUD方法中强制传播.MANDATORY,你必须覆盖这些方法,即
@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);
}
}
希望这会有所帮助