同学你好:
当需要对某个方法开启异步线程,同时开启事务时,即 @Transactional 与 @Async 联合使用。这样使用的一个直接后果是明明加了 @Transactional 注解为什么事务没有成功执行。
原因如下:
(1)Spring 实现这两个注解的方式都是通过 AOP;
(2)在实现时,Async 注解强制覆盖 AOP 的 order 为最小值;
(3)但是在实现 Transactional 注解时,却没有覆盖 order,这意味着它仍然为默认的Integer.MAX_VALUE,order 可配置。所以异步切面会先于事务切面执行;
(4)假设 @Transactional 能先于 Async 切面执行,但由于 spring 事务管理依赖的是 ThreadLocal,所以在开启的异步线程里面感知不到事务,说细点就是在 Spring 开启事务之后,会设置一个连接到当前线程,但这个时候又开启了一个新线程,执行实际的 SQL 代码时,通过 ThreadLocal 获取不到连接就会开启新连接,也不会设置 autoCommit,所以这个函数整体将没有事务。
我是勤一,致力于将这门课程的问答区打造为 Java 知识体系知识库,Java 知识体系 BBS!共同建造、维护这门课程,我需要每一个你!