关于TransactionSynchronizationManager的使用事务问题
背景
相信很多小伙伴在工作中,都遇到过想在这个业务方法执行后,且事务提交成功了,我在去查询XXX,或者业务之类的。 但是你现在已经有的公共抽象方法 不敢轻易乱动。
这个时候你可以用spring预留的口子去执行对应的业务方法, 很多人不清楚这之间的事务关系,我已经给你们整理好啦~
一 、syncToRedis 异步
1、异步 afterCommit 是否能查到提交后的值?
我们把syncToRedis 进行异步处理,看看 A业务进行更新,然后syncToRedis同步操作里面是否获取到最新的值。
结果: syncToRedis虽然是异步的,但是我们也等到事务结束之后select()到了最新的值为N。
下面我们测试 代码异常情况。先把刚才更新为N的恢复为Y状态。
2、异步afterCommit之异常情况下test()是否回滚
我们这次把异常先放到主体代码中也就是test();
结果:
查看堆栈,报了空指针异常 stack_trace":"java.lang.NullPointerException
再看数据库: 发现的确没有被更新为"N"; 证明这个的确是在事务提交之后才执行的。
3、异步afterCommit之异常在afterCommit()是否回滚
结果:
查看堆栈,报了空指针异常 stack_trace":"java.lang.NullPointerException
在查看数据库, 全部更新为"N"了, 那么可以得出, 如果你在afterCommit()方法中抛出异常,那是不会让test()方法回滚的。
4、异步afterCommit之异常在syncToRedis()
结果:
查看堆栈,报了空指针异常 stack_trace":"java.lang.NullPointerException
在查看数据库, 全部更新为"N"了, 那么可以得出, 如果你在syncToRedis()方法中抛出异常,那是不会让test()方法回滚的。
5、异步afterCommit之异常在afterCommit()且UpdateToC
结果:
查看堆栈,报了空指针异常 stack_trace":"java.lang.NullPointerException
在查看数据库, 全部更新为"C"了, 那么可以得出,一定是执行Test()事务,才会执行afterCommit(), 如果你在afterCommit()方法中抛出异常,那是不会让test()方法回滚的。
总结:
前提条件:test()带@Transactional ,且syncToRedis()为async
①test()方法一定是先执行完,才会去执行afterCommit()方法。
②test()方法异常, test方法回滚,且不执行afterCommit()方法。
③ afterCommit()方法内任何方法异常,test()方法不回滚,不影响test()业务。
二、syncToRedis同步带事务
前提条件:test()带@Transactional ,且syncToRedis带@Transactional
直接说总结把:
①test()方法一定是先执行完,才会去执行afterCommit()方法。 同上面
②test()方法异常, test方法回滚,且不执行afterCommit()方法。同上面
③ afterCommit()方法内任何方法异常,test()方法不回滚,不影响test()业务。 同上面
所以你的同步和异步是完全没有任何区别的。