概述
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
}
調用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
}
如果調用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
}
如果調用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
}
調用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
}
調用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
}
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
}
調用methodA,開啟一個事務,執行something pre的代碼,設置回滾點
savepoint,再調用methodB的代碼,如果methodB里拋出異常,此時回滾到之前的saveponint。再然后執行methodA里的something post的代碼,最后提交或者回滾事務。
嵌套事務,外層的事務如果回滾,會導致內層的事務也回滾;但是內層的事務如果回滾,僅僅是回滾自己的代碼,不影響外層的事務的代碼。
