使用Spring管理事务过程中,碰到过一些坑,因此也稍微总结一下,方便后续查阅。 1.代码中事务控制的3种方式
2.事务不回滚的原因 在工作中,看过别人写的代码出现了事务不回滚的现象。当然,事务不回滚的都是采用的声明式事务或者是注解事务;编程式事务都是自己写代码手动回滚的,因此是不会出现不回滚的现象。 再说下声明式事务和注解事务回滚的原理:当被切面切中或者是加了注解的方法中抛出了RuntimeException异常时,Spring会进行事务回滚。默认情况下是捕获到方法的RuntimeException异常,也就是说抛出只要属于运行时的异常(即RuntimeException及其子类)都能回滚;但当抛出一个不属于运行时异常时,事务是不会回滚的。 下面说说我经常见到的3种事务不回滚的产生原因:
3.如何保证事务回滚 正常情况下,按照正确的编码是不会出现事务回滚失败的。下面说几点保证事务能回滚的方法
① 声明式事务,在配置里面添加一个rollback-for,代码如下 1 1 <tx:method name='update*' propagation='REQUIRED' rollback-for='java.lang.Exception'/> ② 注解事务,直接在注解上面指定,代码如下 @Transactional(rollbackFor=Exception.class) 1 1 @Transactional(rollbackFor=Exception.class)
/** TransactionAspectSupport手动回滚事务:*/ @Transactional(rollbackFor = { Exception.class }) public boolean test() { try { doDbSomeThing(); } catch (Exception e) { e.printStackTrace(); //就是这一句了, 加上之后抛了异常就能回滚(有这句代码就不需要再手动抛出运行时异常了) TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return false; } return true; } 1 /** TransactionAspectSupport手动回滚事务:*/ 2 @Transactional(rollbackFor = { Exception.class }) 3 public boolean test() { 4 try { 5 doDbSomeThing(); 6 } catch (Exception e) { 7 e.printStackTrace(); 8 //就是这一句了, 加上之后抛了异常就能回滚(有这句代码就不需要再手动抛出运行时异常了) 9 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 10 return false; 11 } 12 return true; 13 } |
|