在最近的项目中,做的是解析XML文件,解析过程中会有异常,比如:XML文件中节点的数据和与之对应的数据库的字段中数据的类型不匹配;XML中数据长度超过数据库定义的长度;有数据了的重复插入问题;读取节点出错;XML文件路径出错……会遇到很多异常
我的项目使用的是Spring Boot,Spring Data JPA 其中Spring已经封装好了事务,在注解@Transactional中,自动执行事务,出异常自动回滚,但在使用的时候会遇到一些问题:
在多个方法中使用@Transactional,其中一个方法运行时候报错,但是数据却插进去了,但是其他两个方法没有;有时候抛了异常,却不会回滚;方法嵌套的时候执行报错……
查阅了一些资料后,得知是没有正确使用Spring的@Transactional。
下面借用我查到的别人的博客中的例子来说明Spring的@Transactional到底怎么用:
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的总结如下:
1、异常在A方法内抛出,则A方法就得加注解 2、多个方法嵌套调用,如果都有 @Transactional 注解,则产生事务传递,默认 Propagation.REQUIRED 3、如果注解上只写 @Transactional 默认只对 RuntimeException 回滚,而非 Exception 进行回滚
4、如果要对 checked Exceptions 进行回滚,则需要 @Transactional(rollbackFor = Exception.class)