Transactional事务提交后触发异步方法
2019-10-10 17:46
2715 查看
一、问题复现
1.场景
2个service方法, 方法A中调用方法B。
方法A 是核心业务方法,涉及多张表数据变更,为了保持数据一致,用spring事务注解:@Transactional(rollbackFor = Exception.class)
方法B 比较耗时,为了不影响核心业务,方法B 用@Async注解,单独开启一个线程去异步执行。(方法B在另外一个类里边,不能和A在同一个类)。
2.出错原因
方法B是异步方法,导致方法A事务还没提交时(不一定出错,具体就看哪个线程执行的快了)方法B就执行了。
3.期望
期望方法A上的大事务commit后再执行方法B。
二、解决方案
// 注册事务同步处理 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { @Override public void afterCommit() { // 事务提交完毕时,触发:funcB funB(); }
三、原理
提交一个事务同步处理,在事务commit之后执行,具体存放在threadLocal(线程本地变量)中,事务commit时会去threadLocal里边取。源码afterCommit是空的,没有任何操作,可见是spring专门预留给大家使用的。
源码:
TransactionSynchronizationAdapter是一个接口适配器,这样不用实现接口的全部方法,按需Override即可。类图如下图所示:
TransactionSynchronizationAdapter实现了2个接口:
- TransactionSynchronization事务同步接口,
- Ordered执行优先级
我们这里就是实现了TransactionSynchronization接口的afterCommit()方法,最终在事务commit提交后执行。
关于spring事务执行过程图:
四、总结
遇到问题后,很快就想到了处理方式,因为我提前储备了相关知识:
1.spring事务系列(具体在第三章 事务源码,里边有链接)
2.@Async实现异步
3.threadLocal线程本地变量
相关文章推荐
- 事务已被隐式或显式提交,或已终止的解决方法
- WCF分布式开发常见错误(13):此方法调用的事务被异步中断
- 【事务】<查询不到同一调用方法其它事务提交的更新>解决方案
- jquery获取多个checkbox的值异步提交给php的方法
- 数据库事务提交方法和怎样拿到一个insert语句中自动生成的值
- Dapper官方教程翻译11:Dapper方法之异步方法、缓存、事务、存储过程
- asp.net防止刷新重新提交触发后台事件的方法
- jquery ajax异步提交表单数据的方法
- ORACLE数据恢复方法(提交事务也可以)
- 通过Ajax异步提交的方法实现从数据库获取省份和城市信息实现二级联动(xml方法)
- 解决OneThink中无法异步提交kindeditor文本框中修改后的内容方法
- Spring MVC中事务不提交 解决方法
- 表单异步提交的方法
- 如何在数据库事务提交成功后进行异步操作
- Ajax-jQuery.ajax( KV,... )可实现异步和缓存等提交方法
- Ajax异步提交表单数据的说明及方法实例
- Ajax通过XML异步提交的方法实现从数据库获取省份和城市信息实现二级联动(xml方法)
- axios异步提交表单数据的几种方法
- 解决刷新页面造成的Form重复提交触发监听方法
- 表单异步提交的方法