浅析Spring的事务注解和异步注解

1、先给不小心搜到这篇半成品的兄弟结论:

  • @Async注解的方法上,再标注@Transactional注解(不需要特意关注顺序),事务依旧是生效的(但是这个事务是不能跨线程的,见下一点)
  • 不同线程之间的事务完全隔离
  • 异步线程内仍是可以调用异步

2、参考内容

核心技术 (springdoc.cn)

深入理解 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注解。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容