1、先给不小心搜到这篇半成品的兄弟结论:
- @Async注解的方法上,再标注@Transactional注解(不需要特意关注顺序),事务依旧是生效的(但是这个事务是不能跨线程的,见下一点)
- 不同线程之间的事务完全隔离
- 异步线程内仍是可以调用异步
2、参考内容
深入理解 Java 中的 @Transactional 注解:事务管理的精髓解析-阿里云开发者社区 (aliyun.com)
Spring事务王国概览-CSDN博客
Spring事务管理---上_spring事务 createsavepoint-CSDN博客
Spring事务管理---中_@role-CSDN博客
Spring事务管理---下_tx:annotation-driven proxy-target-class-CSDN博客
Spring事务扩展篇_扩展spring事务-CSDN博客
Spring在多线程环境下如何确保事务一致性_spring多线程下的事务安全-CSDN博客
异步事务?关于异步@Async + 事务@Transactional的结合使用问题分析【享学Spring MVC】_@async 事务-CSDN博客
@Async可以和@Transactional结合使用吗?-腾讯云开发者社区-腾讯云 (tencent.com)
@Transactional 能和 @Async 一起用吗? - spring 中文网 (springdoc.cn)
https://shanhai.huawei.com/#/page-forum/post-details?postId=77980
https://wiki.huawei.com/domains/4641/wiki/15219/WIKI20230106623629
@Async与@Transactional同时使用事务未成功执行
2023-01-06 16:40 由 霍金叶 00806446 创建,于2023-01-06 17:33 由 霍金叶 00806446最后修改。
背景
现网数据操作异常,但数据仍存入数据库
问题定位
异步执行数据操作方法,该方法联合使用@Async与@Transactional导致方法的事务失效,未成功执行
场景复现
首先,构建联合使用@Async与@Transactional的异步线程方法,在该方法中插入异步数据
[图片上传失败...(image-181109-1716902458906)]
然后构建使用事务控制的主线程方法,在该方法中插入数据、调用异步方法并显式抛出异常
[图片上传失败...(image-c9b884-1716902458906)]
原始的数据库数据如下
[图片上传失败...(image-29cd08-1716902458906)]
运行主线程方法,从运行结果可以看到主线程异常正常抛出
[图片上传失败...(image-84bdff-1716902458906)]
观察数据库结果如下,虽然主线程异常正常抛出且含有事务控制,但异步方法中的数据插入数据库,主线程的事务控制未成功执行。
[图片上传失败...(image-94fcd3-1716902458906)]
原因分析
Spring 通过AOP实现@Async与@Transactional注解,在实现时@Async强制覆盖AOP的order为最小值,且order不可配置,@Transactional的order为默认的Integer.MAX_VALUE,order可配置。因此如图中所示,异步切面会先于事务切面执行。
[图片上传失败...(image-9e5036-1716902458906)]
结论
方法避免同时使用@Async与@Transactional注解。