Spring 具有传播设置的数据测试存储库

Spring Data test repository with propagation setting

这是一个测试class:

@SpringBootTest
@AutoConfigureMockMvc
@Transactional
public class ValidationTest {
  @Autowired
  private EntityManager entityManager
  ...
}

我想测试服务:

@Transactional(propagation = Propagation.REQUIRES_NEW)
public boolean isEmailUnique(String emailAddress) {
  Optional<User> user = userRepository.findByEmail(emailAddress);
  ...
}

为此,我创建并保存了一个实体:

entityManager.persist(new User(name: "abc", email: "abc@email.com"))
entityManager.flush()

最后调用请求:

mockMvc.perform(post("..."))

userRepository.findByEmail() 没有看到插入的实体,我错过了什么? ps:如果我从方法中删除 @Transactional,那么测试工作正常。

你所处的环境很难理解,因为你只提供了一些片段!但据我所见,我猜...

如果您使用 @Transactional 注释您的测试,每个测试方法都包含一个新的事务,该事务在测试方法执行后自动回滚。

如果您现在在测试方法中准备一些数据,那么它在隐式创建事务的范围内是可见的。如果你然后调用你的服务方法,这个服务方法想要有一个新的事务,这个新的事务不会'see'你在外部事务中准备的数据。如果从服务方法中删除 @Transactional 注释,存储库现在可以 'see' 数据。

如果您查看 Propagation 枚举的 javadoc,您会发现 PROPAGATION_REQUIRES_NEW 是这样描述的:

Create a new transaction, and suspend the current transaction if one exists.

问题是,为什么他们一定需要 new 交易,即使交易已经存在?如果 none 可用,他们就不能创建一个新的,但如果已经存在就使用现有的吗? SUPPORTS 传播就是这种情况,默认情况下在 @Transactional 注释上配置。