REQUIRES_NEW不起作用導致整個事務回滾——Spring事務傳播機制
阿新 • • 發佈:2019-02-12
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方法正確的寫法應該是這樣的:
這樣寫後,REQUIRES_NEW就能起到這個作業啦!@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = RuntimeException.class) @Override public void b() { try { doSomething4B(); throw new RuntimeException();//故意丟擲執行時異常,觀察兩個事務的回滾情況 }catch (Exception e){ //異常處理 } }