在java中異常的基類爲Throwable,他有兩個子類xception與Errors。同時RuntimeException就是Exception的子類,只有RuntimeException纔會進行回滾;java
1,Spring事務回滾機制是這樣的:當所攔截的方法有指定異常拋出,事務纔會自動進行回滾!編程
咱們須要注意的地方有四點: 若是你在開發當中引入Spring進行事務管理,可是事務沒能正常的自動回滾,能夠對照下面四點,缺一不可!app
①被攔截方法-—— 註解式:方法或者方法所在類被@Transactional註解;.net
②異常—— 該方法的執行過程必須出現異常,這樣事務管理器才能被觸發,並對此作出處理;blog
③指定異常—— 默認配置下,事務只會對Error與RuntimeException及其子類這些UNChecked異常,作出回滾。 通常的Exception這些Checked異常不會發生回滾(若是通常Exception想回滾要作出配置);事務
舉例:實現通常異常的回滾:開發
註解式:io
@Transactional(rollbackFor=Exception.class) @RequestMapping("consump") public void insertConsumption(Customer c,Consumption s,Mygift m) throws Exception{ }
④異常拋出—— 即方法中出現的指定異常,只有在被事務管理器捕捉到之後,事務纔會據此進行事務回滾;class
1,不捕捉,會回滾:email
public void insertConsumption(Customer c,Consumption s,Mygift m) throws Exception{ int a=consumpDao.insert(s); int b=customerDao.update(customer); }
2,若是異常被try{}捕捉到,那麼事務管理器就沒法再捕捉異常,因此就沒法作出反應,事務不回滾;
public void insertConsumption(Customer c,Consumption s,Mygift m) throws Exception{ try{ }catch(RuntimeException){ } }
3,若是異常被try{}捕捉了,咱們還能夠在Catch(){}中throw new RuntimeException(),手動拋出運行時異常供事務管理器捕捉;
public void insertConsumption(Customer c,Consumption s,Mygift m) throws Exception{ try{ }catch(){ throw new RuntimeException(); } }
2,在實際開發中,有時並無異常發生,可是因爲事務結果未知足具體業務需求,因此咱們不得不手動回滾事務!
有以下兩種方法:
①手動拋出異常(若是你沒有配置通常異常事務回滾,請拋出運行時異常)
if(){ }else{ throw new RuntimeException(); }
②編程式實現手動回滾
if(){ }else{ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); }
轉自:https://my.oschina.net/gaomq/blog/1580290?email=Xie.Chaoyue@outlook.com