背景
相信很多小伙伴在工作中,都遇到過想在這個業務方法執行后,且事務提交成功了,我在去查詢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()業務。 同上面
所以你的同步和異步是完全沒有任何區別的。