轉(zhuǎn)自:http://blog.csdn.net/zhu_tianwei/article/details/72848654
在實際項目開發(fā)中函喉,經(jīng)常會由于配置錯誤或使用不當,導致spring事務管理不生效浸卦。如下總結了幾點事務不生效的情況:
1裸违、確認創(chuàng)建的mysql數(shù)據(jù)庫表引擎是InnoDB目锭,MyISAM不支持事務荧呐。
2、確認調(diào)用的類是由spring容器管理的代理類擅憔。
AopUtils.isAopProxy(Object object)
AopUtils.isCglibProxy(Object object) //cglib
AopUtils.isJdkDynamicProxy(Object object) //jdk動態(tài)代理
<aop:config proxy-target-class="true" />可強制cglib代理
3鸵闪、調(diào)用的方法必須是public,否則事務不起作用暑诸。這一點由Spring的AOP特性決定的蚌讼。
4、spring切點是否配置錯誤个榕,或使用了springmvc篡石,可能是context:component-scan重復掃描引起的。
5西采、拋出一個runtimeException才能回滾凰萨。
Spring使用聲明式事務處理,默認情況下械馆,如果被注解的數(shù)據(jù)庫操作方法中發(fā)生了unchecked異常胖眷,所有的數(shù)據(jù)庫操作將rollback;如果發(fā)生的異常是checked異常狱杰,默認情況下數(shù)據(jù)庫操作還是會提交的瘦材。
Java異常之checked與unchecked:http://www.cnblogs.com/shihuc/p/5201905.html
Exception這個父類是checked類型,但是其子類RuntimeException (子類NullPointerException等)是unchecked的仿畸。
6食棕、Spring的事務傳播策略在內(nèi)部方法調(diào)用時將不起作用。
public int save(String name, int age) throws Exception {
insert(name, age);
return 1;
}
@Transactional
public void insert(String name, int age){
jdbcTemplate.update("insert into user(id,name,age)values(1,'"+name+"',"+age+")");
jdbcTemplate.update("insert into user(id,name,age)values(2,'"+name+"',"+age+")");
jdbcTemplate.update("insert into user(id,name,age)values(1,'"+name+"',"+age+")");
}
Spring事務的傳播機制:
Propagation支持7種不同的傳播機制:
REQUIRED:如果存在一個事務错沽,則支持當前事務簿晓。如果沒有事務則開啟一個新的事務。
SUPPORTS: 如果存在一個事務千埃,支持當前事務憔儿。如果沒有事務,則非事務的執(zhí)行放可。但是對于事務同步的事務管理器谒臼,PROPAGATION_SUPPORTS與不使用事務有少許不同。
NOT_SUPPORTED:總是非事務地執(zhí)行耀里,并掛起任何存在的事務蜈缤。
REQUIRESNEW:總是開啟一個新的事務。如果一個事務已經(jīng)存在冯挎,則將這個存在的事務掛起底哥。
MANDATORY:如果已經(jīng)存在一個事務,支持當前事務。如果沒有一個活動的事務趾徽,則拋出異常续滋。
NEVER:總是非事務地執(zhí)行,如果存在一個活動事務孵奶,則拋出異常
NESTED:如果一個活動的事務存在疲酌,則運行在一個嵌套的事務中。如果沒有活動事務拒课,則按REQUIRED屬性執(zhí)行徐勃。