如何在 Spring 引导服务中声明 `@Transactional` 从而引发异常 "immediately"?

How to declare `@Transactional` in a Spring Boot service so exception is thrown "immediately"?

假设我在 spring 引导应用程序中有以下 spring beans。我的目的是使 createFoo() 具有事务性,因此:

  1. barService.bar() 抛出异常时,持久化被回滚。
  2. 当持久化抛出异常时,异常传播到调用者 "immediately" 所以 barService.bar() 不会被调用 .
@Service
public class FooService
{
    @Autowired
    private FooRepository fooRepository;
    @Autowired
    private BarService barService;

    @Transactional
    public void createFoo(Foo foo) {
        fooRepository.save(foo);
        // expect to not execute when the above line throws exceptions
        barService.bar();
    }
}

@Service
public class BarService {
    public void bar() {

    }
}

到目前为止,第一个要求有效,但第二个要求无效。当持久化抛出异常时,barService.bar() 总是被调用.

如果我删除 @Transactional,第二个要求有效,第一个无效。

我还尝试了所有 Propagation 类型,其中 none 可以正常工作。例如,如果我使用 @Transactional(MANDATORY),我会得到以下错误:

org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'

如果没有 @Transactional,对 repo 方法的每次调用都是一个独立的事务,它将立即被刷新。这就是为什么您的第二个要求在没有 @Transactional.

的情况下起作用的原因

当您添加 @Transactional 时,整个 createFoo() 成为一个交易单位。因此,您在调用 save() 时所做的更改只会在 createFoo() 完成执行时刷新。这就是为什么您的第一个要求适用于 @Transactional.

要实现您想要的效果,请保留 @Transactional 并调用 saveAndFlush() 而不是 save()