Spring的事務傳播機制(通俗易懂)
概述
Spring的事務傳播機制有7種,在列舉Propagation中有定義。
1.REQUIRED
PROPAGATION_REQUIRED:如果當前沒有事務,就建立一個新事務,如果當前存在事務,就加入該事務,該設定是最常用的預設設定。
@Transactional(propagation= Propagation.REQUIRED)
public void methodA(){
methodB();
// do something
}
@Transactional
(propagation= Propagation.REQUIRED)
public void methodB(){
// do something
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
呼叫methdoA,如果methodB發生異常,觸發事務回滾,也會methodA中的也會回滾。
2.SUPPORTS
PROPAGATION_SUPPORTS:支援當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就以非事務執行。
@Transactional(propagation= Propagation.REQUIRED)
public void methodA(){
methodB() ;
// do something
}
@Transactional(propagation= Propagation.SUPPORTS)
public void methodB(){
// do something
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如果呼叫methodA,再呼叫methodB,MehtodB會加入到MethodA的開啟的當前事務中。
如果直接呼叫methodB,當前沒有事務,就以非事務執行。
3.MANDATORY
PROPAGATION_MANDATORY:支援當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就丟擲異常。
@Transactional (propagation= Propagation.REQUIRED)
public void methodA(){
methodB();
// do something
}
@Transactional(propagation= Propagation.MANDATORY)
public void methodB(){
// do something
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如果呼叫methodA,再呼叫methodB,MehtodB會加入到MethodA的開啟的當前事務中。
如果直接呼叫methodB,當前沒有事務,就會丟擲異常。
4.REQUIRES_NEW
PROPAGATION_REQUIRES_NEW:建立新事務,無論當前存不存在事務,都建立新事務。
@Transactional(propagation= Propagation.REQUIRED)
public void methodA(){
// do something pre
methodB();
// do something post
}
@Transactional(propagation= Propagation.REQUIRES_NEW)
public void methodB(){
// do something
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
呼叫methodA,會先開啟事務1,執行A的something pre的程式碼。再呼叫methodB,methdoB會開啟一個事務2,再執行自身的程式碼。最後在執行methodA的something post。如果method發生異常回滾,只是methodB中的程式碼回滾,不影響methodA中的程式碼。如果methodA發生異常回滾,只回滾methodA中的程式碼,不影響methodB中的程式碼。
簡言之,不會影響別人,也不會被別人影響。
5.NOT_SUPPORTED
PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
@Transactional(propagation= Propagation.REQUIRED)
public void methodA(){
methodB();
// do something
}
@Transactional(propagation= Propagation.NOT_SUPPORTED)
public void methodB(){
// do something
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
呼叫methodA,再呼叫methodB,methodA開啟的事務會被掛起,即在methodB中不齊作用,相當於沒有事務,methodB內部丟擲異常不會回滾。methodA內的程式碼發生異常會回滾。
直接呼叫methodB,不會開啟事務。
6.NEVER
PROPAGATION_NEVER:以非事務方式執行操作,如果當前存在事務,則丟擲異常。
@Transactional(propagation= Propagation.REQUIRED)
public void methodA(){
methodB();
// do something
}
@Transactional(propagation= Propagation.NEVER)
public void methodB(){
// do something
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
7. NESTED
PROPAGATION_NESTED:如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則按REQUIRED屬性執行。
@Transactional(propagation= Propagation.REQUIRED)
public void methodA(){
// do something pre
methodB();
// do something post
}
@Transactional(propagation= Propagation.NESTED)
public void methodB(){
// do something
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
呼叫methodA,開啟一個事務,執行something pre的程式碼,設定回滾點
savepoint
,再呼叫methodB的程式碼,如果methodB裡丟擲異常,此時回滾到之前的saveponint。再然後執行methodA裡的something post的程式碼,最後提交或者回滾事務。
巢狀事務,外層的事務如果回滾,會導致內層的事務也回滾;但是內層的事務如果回滾,僅僅是回滾自己的程式碼,不影響外層的事務的程式碼。