@Transactional事務生效問題

平時我們使用spring框架,不論是springmvcv還是springboot,springCloud,絕大多數情況我們都是在方法,或者直接在類上面加一個@Transactional,將事務交給spring替我們去管理,然後並沒有具體分析一些情況,今天結合幾個例子,結合源代碼,使用僞代碼解釋一波。
1.情況一

   service(){
       //方法A
       methodA(){
           insertA();
       }
       //方法B
       @Transactional
       methodB(){
           insertB();
           throw new RunTimeException("強制拋一個異常");
       }
       public void static main(String[] args){
           methodA();
           methodB();
       }
   }

情況一就是這樣,main方法裏面順序調用AB兩個方法,A方法不加事務註解,B方法加了事務註解。如果不瞭解@Transactional 事務的傳播性,可能會回答:A成功插入,B插入失敗,但是實際情況卻是A,B均插入成功了。到底是什麼原因呢?這裏先簡單介紹一下事務的6個傳播屬性:

PROPAGATION_REQUIRED : 支持當前事務,如果當前沒有事務,就新建一個事務,這也是最常見的
PROPAGATION_SUPPORTS : 支持當前事務,如果當前沒有事務,就以非事務的方式執行
PROPAGATION_MANDATORY: 支持當前事務,如果當前沒有事務,就拋異常
PROPAGATION_REQUIRES_NEW:新建事務,如果當前事務存在,就把當前事務掛起
PROPAGATION_NOT_SUPPORTED:以非事務的方式執行,如果存在當前事務,就把當前事務掛起
PROPAGATION_NEVER: 以非事務的方式執行,如果當前存在事務,就拋異常
PROPAGATION_NESTED:如果存在當前事務,則在嵌套事務內執行,如果當前沒有事務,則新建一個事務

前六個策略類似於EJB CMT,第七個(PROPAGATION_NESTED)是Spring所提供的一個特殊變量。

研究源碼,調試程序可以看到:
A沒有事務管理,則線程內的connection 有個autoCommit = true
B得到事務的時候,由於事務的傳播性依然生效, 得到的還是A方法的commit,其autoCommit = true,故而逐條sql進行提交,即A,B都會插入

下面我們來分析情況二:

serviceA(){
    methodA(){
        insertA();
    }
} 
serviceB(){
    @Transactional
    methodB(){
        insertB();
        throw new RuntimeExcption("強制拋出的異常");
    }
}
serviceC(){
    @Autowired
    private ServiceA serviceA;
    @Autowired
    private ServiceB serviceB;

    public void staic main(String[] args){
        serviceA.methodA();
        serviceB.methodB();
    }
}


情況二的主要代碼和情況一一樣,都是要調用methodA和methodB,但是結果卻不同,情況二的正確結果是指揮插入A,而B會回滾,這是爲什麼呢?同樣是在B方法上面加了事務註解....

其實大家都知道,spring的事務是交由cglib動態代理的,而動態代理對象產生的時機就非常重要了。再回到本例子:

A:在同一個service內部,事務之間嵌套調用,普通方法和事務方法之間的嵌套調用,都不會開啓新的事務(因爲shpring使用的是動態代理的方式來控制的事務,而動態代理最終都是要調用原始對象的,而原始對象在調用方法時,已存在代理對象,是不會再觸發代理了!)
B:兩個方法在不同的service裏(即不同的對象,即代理對象也不是同一個),在ServiceC中,使用注入的方式將serviceA和serviceB注入,這樣即使A沒有使用事務,B也有自己的代理,會根據PROPAGATION_REQUIRED 而生成新的事務.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章