处理springboot 下提交事务异常,数据库没有回滚的问题。
spring的文档中说道,spring声明式事务管理默认对非检查型异常和运行时异常进行事务回滚,而对检查型异常则不进行回滚操作。
什么是检查型异常什么又是非检查型异常?
最简单的判断点有两个:
1.继承自runtimeexception或error的是非检查型异常,而继承自exception的则是检查型异常(当然,runtimeexception本身也是exception的子类)。
2.对非检查型类异常可以不用捕获,而检查型异常则必须用try语句块进行处理或者把异常交给上级方法处理总之就是必须写代码处理它。所以必须在service捕获异常,然后再次抛出,这样事务方才起效。
结论:
在spring的事务管理环境下,使用unckecked exception可以极大地简化异常的处理,只需要在事务层声明可能抛出的异常(这里的异常可以是自定义的unckecked exception体系),在所有的中间层都只是需要简单throws即可,不需要捕捉和处理,直接到最高层,比如UI层再进行异常的捕捉和处理。
默认规则:
1 让checked例外也回滚: @Transactional(rollbackFor=Exception.class),一般只需添加这个即可
2 让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)
3 不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED),或者不添加
注意: 如果异常被try{}catch{}了,事务就不回滚了,如果想让事务回滚必须再往外抛try{}catch{throw Exception}。因为一旦你try{}catch{}了。系统会认为你已经手动处理了异常,就不会进行回滚操作。
示例:
spring 事务控制 设置手动回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
https://www.cnblogs.com/liuzhenlei/p/6777644.html
如上:
当我们需要在事务控制的service层类中使用try catch 去捕获异常后,就会使事务控制失效,因为该类的异常并没有抛出,就不是触发事务管理机制。怎样才能即使用try catch去捕获异常,而又让出现异常后spring回滚呢,这里就要用到
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
完美解决问题。并且能够使该方法执行完。
这个需要注意两点:
1. 方法上要加上 @Transactional(rollbackFor = Exception.class) 再配合TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 才可以,
否则会报错 NoTransactionException: No transaction aspect-managed TransactionStatus in scope
at
2. Spring Transactional一直是RD的事务神器,但是如果用不好,反会伤了自己。下面总结@Transactional经常遇到的几个场景:
Transactional是否生效, 仅取决于是否加载于接口方法, 并且是否通过接口方法调用(而不是本类调用)。
https://segmentfault.com/a/1190000014617571
3.在web项目中,很多时候要用到@Transactional 注解方法或者类进行事务处理,自动事务提交有时候就会有问题,这个时候就要用到手动进行事务提交 ,在try catch 异常抛出里面手动回滚事务处理TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
使用Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint(); 设置回滚点,
使用TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);回滚到savePoint。
转自:
https://blog.csdn.net/zhuchunyan_aijia/article/details/80191534