@Transactional与@Async可以同时使用吗
原因:
- Spring 的事务管理依赖于线程上下文,但
@Async
方法在新的线程中执行,而事务信息默认是存储在线程本地变量(ThreadLocal)中的,因此 新线程无法继承主线程的事务,导致@Transactional
失效。 - Spring 代理(AOP)不会拦截自身方法的调用,如果该方法是 被同一类中的另一个方法调用,Spring 事务代理不会生效。
方法 1:让 @Transactional
在 @Async
方法外层
@Service public class MyService { @Autowired private MyService self; // 通过 AOP 代理调用自身的方法 @Transactional public void transactionalMethod() { // 在事务内调用异步方法 self.asyncMethod(); } @Async public void asyncMethod() { // 这个方法可以异步执行 System.out.println("异步执行的任务:" + Thread.currentThread().getName()); } }
方法 2:在 @Async
方法内部使用新事务
@Service public class MyService { @Async public void asyncMethod() { saveDataWithTransaction(); // 调用一个带事务的方法 } @Transactional public void saveDataWithTransaction() { // 这个方法在新线程中会开启新的事务 } }