在最近的項目中,作的是解析XML文件,解析過程當中會有異常,好比:XML文件中節點的數據和與之對應的數據庫的字段中數據的類型不匹配;XML中數據長度超過數據庫定義的長度;有數據了的重複插入問題;讀取節點出錯;XML文件路徑出錯……會遇到不少異常數據庫
個人項目使用的是Spring Boot,Spring Data JPA 其中Spring已經封裝好了事務,在註解@Transactional中,自動執行事務,出異常自動回滾,但在使用的時候會遇到一些問題:this
在多個方法中使用@Transactional,其中一個方法運行時候報錯,可是數據卻插進去了,可是其餘兩個方法沒有;有時候拋了異常,卻不會回滾;方法嵌套的時候執行報錯……spa
查閱了一些資料後,得知是沒有正確使用Spring的@Transactional。code
下面借用我查到的別人的博客中的例子來講明Spring的@Transactional到底怎麼用:blog
1 @Service 2 public class SysConfigService { 3 4 @Autowired 5 private SysConfigRepository sysConfigRepository; 6 7 public SysConfigEntity getSysConfig(String keyName) { 8 SysConfigEntity entity = sysConfigRepository.findOne(keyName); 9 return entity; 10 } 11 12 public SysConfigEntity saveSysConfig(SysConfigEntity entity) { 13 14 if(entity.getCreateTime()==null){ 15 entity.setCreateTime(new Date()); 16 } 17 18 return sysConfigRepository.save(entity); 19 20 } 21 22 @Transactional 23 public void testSysConfig(SysConfigEntity entity) throws Exception { 24 //不會回滾 25 this.saveSysConfig(entity); 26 throw new Exception("sysconfig error"); 27 28 } 29 30 @Transactional(rollbackFor = Exception.class) 31 public void testSysConfig1(SysConfigEntity entity) throws Exception { 32 //會回滾 33 this.saveSysConfig(entity); 34 throw new Exception("sysconfig error"); 35 36 } 37 38 @Transactional 39 public void testSysConfig2(SysConfigEntity entity) throws Exception { 40 //會回滾 41 this.saveSysConfig(entity); 42 throw new RuntimeException("sysconfig error"); 43 44 } 45 46 @Transactional 47 public void testSysConfig3(SysConfigEntity entity) throws Exception { 48 //事務仍然會被提交 49 this.testSysConfig4(entity); 50 throw new Exception("sysconfig error"); 51 } 52 53 @Transactional(rollbackFor = Exception.class) 54 public void testSysConfig4(SysConfigEntity entity) throws Exception { 55 56 this.saveSysConfig(entity); 57 } 58 59 60 61 }
對於經常使用的Spring的@Transactional的總結以下:事務
一、異常在A方法內拋出,則A方法就得加註解 二、多個方法嵌套調用,若是都有 @Transactional 註解,則產生事務傳遞,默認 Propagation.REQUIRED 三、若是註解上只寫 @Transactional 默認只對 RuntimeException 回滾,而非 Exception 進行回滾四、若是要對 checked Exceptions 進行回滾,則須要 @Transactional(rollbackFor = Exception.class)