前言
@Transactional介紹
transactionManager
isolation
propagation
-
表明事務的傳播行爲,默認值爲
Propagation.REQUIRED
。
-
Propagation.REQUIRED
:若是存在一個事務,則支持當前事務。若是沒有事務則開啓一個新的事務。好比A方法內部調用了B方法,此時B方法將會使用A方法的事務。
-
Propagation.MANDATORY
:支持當前事務,若是當前沒有事務,就拋出異常。
-
Propagation.NEVER
:以非事務方式執行,若是當前存在事務,則拋出異常。
-
Propagation.NOT_SUPPORTED
:以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。
-
Propagation.REQUIRES_NEW
:新建事務,若是當前存在事務,把當前事務掛起。好比A方法使用默認的事務傳播屬性,B方法使用
REQUIRES_NEW
,此時A方法在內部調用B方法,一旦A方法出現異常,A方法中的事務回滾了,可是B方法並無回滾,由於A和B方法使用的不是同一個事務,B方法新建了一個事務。
-
Propagation.NESTED
:支持當前事務,新增
Savepoint
點,也就是在進入子事務以前,父事務創建一個回滾點,與當前事務同步提交或回滾。 子事務是父事務的一部分,在父事務還未提交時,子事務必定沒有提交。嵌套事務一個很是重要的概念就是內層事務依賴於外層事務。外層事務失敗時,會回滾內層事務所作的動做。而內層事務操做失敗並不會引發外層事務的回滾。
timeout
readOnly
rollbackFor 屬性
noRollbackFor
@Transactional失效場景
底層數據庫引擎不支持事務
在非public修飾的方法使用
protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
複製代碼
異常被 " 踹死了 "
@Transactional
public void method(){
try{
}catch(Exception ex){
return;
}
}
複製代碼
方法中調用同類的方法
public class Test{
public void A(){
B();
}
@Transactional
public void B(){
}
}
複製代碼
-
爲何會失效呢?:其實緣由很簡單,Spring在掃描Bean的時候會自動爲標註了
@Transactional
註解的類生成一個代理類(proxy),當有註解的方法被調用的時候,其實是代理類調用的,代理類在調用以前會開啓事務,執行事務的操做,可是同類中的方法互相調用,至關於
this.B()
,此時的B方法並不是是代理類調用,而是直接經過原有的Bean直接調用,因此註解會失效。
-
如何解決呢?:這就涉及到註解失效的緣由了,後續文章會介紹到,這裏不過多介紹了。
rollbackFor屬性設置錯誤
noRollbackFor屬性設置錯誤
propagation屬性設置錯誤
-
事務的傳播屬性在上面已經介紹了,默認的事務傳播屬性是
Propagation.REQUIRED
,可是一旦配置了錯誤的傳播屬性,也是會致使事務失效,以下三種配置將會致使事務失效:
原始SSM項目,重複掃描致使事務失效
-
在原始的SSM項目中都配置了
context:component-scan
而且同時掃描了service層,此時事務將會失效。
-
按照Spring配置文件的加載順序來講,會先加載Springmvc的配置文件,若是在加載Springmvc配置文件的時候把service也加載了,可是此時事務還沒加載,將會致使事務沒法成功生效。
-
解決方法很簡單,把掃描service層的配置設置在Spring配置文件或者其餘配置文件中便可。
總結