1. 程式人生 > >REQUIRES_NEW不起作用導致整個事務回滾——Spring事務傳播機制

REQUIRES_NEW不起作用導致整個事務回滾——Spring事務傳播機制

1、Propagation.REQUIRES_NEW的作用

假設有個物件A,有a()方法,有個物件B,有b()方法。在a方法中呼叫了b方法,b方法被稱為內嵌事務,不管a方法是否開啟事務,只要b方法的事務的隔離級別為REQUIRES_NEW,則一定會在呼叫b方法時產生一個新的事務。

2、一個場景

A的a()方法:

    @Transactional
    public void a() {
        doSomething4A();
        B.b();//可能會丟擲執行時異常
    }

內嵌在A中的B.b()方法:

    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = RuntimeException.class)
    @Override
    public void b() {
        doSomething4B();
        throw new RuntimeException();//故意丟擲執行時異常,觀察兩個事務的回滾情況
    }

在這時你肯定會想,doSomething4A會執行成功,而doSomething4B會回滾,因為我們的內嵌事務b方法的隔離級別是REQUIRES_NEW,這個方法是在一個新的事務中,回滾之後不會影響外部事務。

錯錯錯!

事實上的執行結果是兩個事務都回滾了!為什麼?難道是REQUIRES_NEW失效了?

不是!仔細觀察這段程式碼,b方法丟擲異常後,並沒有顯示捕獲,而是拋到了a方法裡,a方法執行中遇到了執行時異常,也回滾了!所以b方法正確的寫法應該是這樣的:

    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = RuntimeException.class)
    @Override
    public void b() {
        try {
            doSomething4B();
            throw new RuntimeException();//故意丟擲執行時異常,觀察兩個事務的回滾情況
        }catch (Exception e){
            //異常處理
        }
    }
這樣寫後,REQUIRES_NEW就能起到這個作業啦!