試驗方法:
寫一個單元測試,調用一個service層方法(發生對數據庫進行寫操作的方法--insert、update、delete)即可.
試驗過程:
定義一個service方法如下:
public SMSTiming createSMSTiming(SMSTiming smsTiming){
SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);
return s;
}
定義二個異常(先默認配置TestException爲spring事務回滾異常):
publicclass MyTestException extends Exception
publicclass TestException extends Exception
注意看下:每次這個方法的不同處(拋出的異常不同)。
測試1:
public SMSTiming createSMSTiming(SMSTiming smsTiming){
SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);
int i = 4/0; //人爲產生異常(實際這裏拋出了ArithmeticException運行異常)
return s;
}
測試1結果:會事務回滾----數據庫中未插入新數據。
測試2:
public SMSTiming createSMSTiming(SMSTiming smsTiming) throws Exception{//受檢異常(非運行異常)必須拋出
SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);
try{
int i = 4/0; //人爲產生異常
}catch(Exception e){
thrownew Exception ("");//拋出Exception異常
}
return s;
}
測試2結果:不會事務回滾----數據庫中插入新數據。
測試3:
public SMSTiming createSMSTiming(SMSTiming smsTiming) throws RuntimeException{//運行異常(非受檢異常)可以不拋出
SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);
try{
int i = 4/0; //人爲產生異常
}catch(Exception e){
thrownewRuntimeException("");//拋出RuntimeException異常
}
return s;
}
測試3結果:會事務回滾----數據庫中未插入新數據
測試4:
public SMSTiming createSMSTiming(SMSTiming smsTiming) throws TestException{//受檢異常(非運行異常)必須拋出
SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);
try{
int i = 4/0; //人爲產生異常
}catch(Exception e){
thrownewTestException("");//拋出TestException異常
}
return s;
}
測試4結果:會事務回滾----數據庫中未插入新數據。
測試5:
public SMSTiming createSMSTiming(SMSTiming smsTiming) throws MyTestException{//受檢異常(非運行異常)必須拋出
SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);
try{
int i = 4/0; //人爲產生異常
}catch(Exception e){
thrownewMyTestException("");//拋出MyTestException異常
}
return s;
}
測試5結果:不會事務回滾----數據庫中插入新數據。
測試6:
public SMSTiming createSMSTiming(SMSTiming smsTiming) throws MyTestException{//受檢異常(非運行異常)必須拋出 (注意:此時spring指定配置此異常回滾)
SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);
try{
int i = 4/0; //人爲產生異常
}catch(Exception e){
thrownewMyTestException("");//拋出MyTestException異常
}
return s;
}
測試6結果:會事務回滾----數據庫中未插入新數據。
試驗總結:
測試1、測試3、測試4、測試6會進行事務回滾;測試2、測試5不會進行事務回滾。
爲什麼會這樣?因爲是異常的類型(受檢異常、運行時異常)不同或使用了Spring的rollback-for配置。
測試1和測試3是因爲拋出了運行時異常,會事務回滾。
測試4和測試5、測試6分別拋出受檢異常TestException、MyTestException,那爲什麼測試4和測試6會事務回滾呢?
因爲是我們在Spring事務配置中指定了此異常(指定rollback-for)。
Spring框架的事務基礎架構代碼將默認地 只 在拋出運行時和unchecked
exceptions時才標識事務回滾。 也就是說,當拋出一個 RuntimeException
或其子類例的實例時。(Errors
也一樣 - 默認地 - 標識事務回滾。)從事務方法中拋出的Checked exceptions將 不 被標識進行事務回滾
資料:
1. http://hi.baidu.com/thrunder_liu/blog/item/e3a5b60132b31281e950cd87.html
2. http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html