2個service方法, 方法A中調用方法B。html
方法A 是核心業務方法,涉及多張表數據變動,爲了保持數據一致,用spring事務註解:@Transactional(rollbackFor = Exception.class)spring
方法B 比較耗時,爲了避免影響核心業務,方法B 用@Async註解,單獨開啓一個線程去異步執行。(方法B在另一個類裏邊,不能和A在同一個類)。異步
方法B是異步方法,致使方法A事務還沒提交時(不必定出錯,具體就看哪一個線程執行的快了)方法B就執行了。ide
指望方法A上的大事務commit後再執行方法B。post
1 // 註冊事務同步處理 2 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { 3 @Override 4 public void afterCommit() { 5 // 事務提交完畢時,觸發:funcB 6 funB(); 7 }
提交一個事務同步處理,在事務commit以後執行,具體存放在threadLocal(線程本地變量)中,事務commit時會去threadLocal裏邊取。源碼afterCommit是空的,沒有任何操做,可見是spring專門預留給你們使用的。url
源碼:spa
TransactionSynchronizationAdapter是一個接口適配器,這樣不用實現接口的所有方法,按需Override便可。類圖以下圖所示:線程
TransactionSynchronizationAdapter實現了2個接口:code
咱們這裏就是實現了TransactionSynchronization接口的afterCommit()方法,最終在事務commit提交後執行。
關於spring事務執行過程圖:
htm
遇到問題後,很快就想到了處理方式,由於我提早儲備了相關知識:
1.spring事務系列(具體在第三章 事務源碼,裏邊有連接)
2.@Async實現異步
3.threadLocal線程本地變量