@Async与@Transactional注解下CompletableFuture的事务回滚问题
问题解答
当messageRepository.save(new Message("saved new bundle with name {}", name);调用失败时,bundleRepository.save(new Bundle(name));的操作不会触发事务回滚,原因如下:
- Spring的
@Transactional注解依赖ThreadLocal管理事务上下文,只有同一线程内的操作才会归属到同一个事务中。 - 你在标注了
@Async的方法内部又调用了CompletableFuture.supplyAsync(),这会把内部逻辑提交到另一个线程池(默认是ForkJoinPool)执行,和@Async注解指定的异步线程不是同一个。因此@Transactional的事务上下文无法覆盖supplyAsync内部的代码,这部分逻辑完全处于无事务环境。 bundleRepository.save执行后会直接提交到数据库,后续messageRepository.save抛出异常时,前面的bundle数据已经持久化,不存在事务回滚的基础。
另外你的代码存在两处语法错误:
messageRepository.save(new Message("saved new bundle with name {}", name);缺少闭合的右括号exceptionally(throwable -> { ... );缺少闭合的大括号和右括号
内容的提问来源于stack exchange,提问作者Thomas Lang
相关产品推荐
相关产品推荐

