轉(zhuǎn)自:http://blog.csdn.net/zhu_tianwei/article/details/72848654
在實際項目開發(fā)中,經(jīng)常會由于配置錯誤或使用不當(dāng),導(dǎo)致spring事務(wù)管理不生效。如下總結(jié)了幾點事務(wù)不生效的情況:
1、確認(rèn)創(chuàng)建的mysql數(shù)據(jù)庫表引擎是InnoDB,MyISAM不支持事務(wù)。
2、確認(rèn)調(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" />可強(qiáng)制cglib代理
3、調(diào)用的方法必須是public,否則事務(wù)不起作用。這一點由Spring的AOP特性決定的。
4、spring切點是否配置錯誤,或使用了springmvc,可能是context:component-scan重復(fù)掃描引起的。
5、拋出一個runtimeException才能回滾。
Spring使用聲明式事務(wù)處理,默認(rèn)情況下,如果被注解的數(shù)據(jù)庫操作方法中發(fā)生了unchecked異常,所有的數(shù)據(jù)庫操作將rollback;如果發(fā)生的異常是checked異常,默認(rèn)情況下數(shù)據(jù)庫操作還是會提交的。
Java異常之checked與unchecked:http://www.cnblogs.com/shihuc/p/5201905.html
Exception這個父類是checked類型,但是其子類RuntimeException (子類NullPointerException等)是unchecked的。

6、Spring的事務(wù)傳播策略在內(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事務(wù)的傳播機(jī)制:
Propagation支持7種不同的傳播機(jī)制:
REQUIRED:如果存在一個事務(wù),則支持當(dāng)前事務(wù)。如果沒有事務(wù)則開啟一個新的事務(wù)。
SUPPORTS: 如果存在一個事務(wù),支持當(dāng)前事務(wù)。如果沒有事務(wù),則非事務(wù)的執(zhí)行。但是對于事務(wù)同步的事務(wù)管理器,PROPAGATION_SUPPORTS與不使用事務(wù)有少許不同。
NOT_SUPPORTED:總是非事務(wù)地執(zhí)行,并掛起任何存在的事務(wù)。
REQUIRESNEW:總是開啟一個新的事務(wù)。如果一個事務(wù)已經(jīng)存在,則將這個存在的事務(wù)掛起。
MANDATORY:如果已經(jīng)存在一個事務(wù),支持當(dāng)前事務(wù)。如果沒有一個活動的事務(wù),則拋出異常。
NEVER:總是非事務(wù)地執(zhí)行,如果存在一個活動事務(wù),則拋出異常
NESTED:如果一個活動的事務(wù)存在,則運(yùn)行在一個嵌套的事務(wù)中。如果沒有活動事務(wù),則按REQUIRED屬性執(zhí)行。