CompletableFuture导致@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)失效,如何解决
时间: 2023-07-21 12:19:59 AIGC 浏览: 308
在使用 CompletableFuture 时,如果你使用了 @Transactional 注解,在某些情况下可能会导致事务失效。这是由于 CompletableFuture 默认会在一个新的线程中执行任务,而新线程中没有继承原有线程的事务上下文,因此事务会被挂起,导致 @Transactional 失效。
要解决这个问题,你需要将事务的传播属性设置为 REQUIRES_NEW,这样每个 CompletableFuture 任务都会在新的事务中执行,并且不会受到外部事务的影响。可以在 CompletableFuture 中使用 runAsync() 和 supplyAsync() 方法,将任务提交到线程池中执行,并设置事务的传播属性为 REQUIRES_NEW,示例如下:
```
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
// 业务逻辑
}, executor).thenRunAsync(() -> {
// 业务逻辑
}, executor);
future.get(); // 等待任务执行完成
```
在上面的代码中,executor 是一个线程池,可以自己创建。在使用 CompletableFuture 时,需要注意避免使用它的 join() 方法,因为它会阻塞当前线程,导致事务失效。
另外,如果你使用的是 Spring Boot,还可以考虑使用 @Async 注解来异步执行任务,它会自动处理事务的传播属性,示例如下:
```
@Service
public class SomeService {
@Async
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public CompletableFuture<Void> doSomethingAsync() {
// 业务逻辑
}
}
```
在上面的代码中,使用了 @Async 注解来异步执行任务,并且在方法上同时标注了 @Transactional 注解,设置了事务的传播属性为 REQUIRES_NEW,这样就可以避免事务失效的问题。
阅读全文
相关推荐


















