Spring事务默认回滚规则
背景
今天搭建公司SpringBoot基础框架时,在设计自定义异常阶段,参考其他框架优秀源码发现都是继承了 RuntimeException,为何不直接继承 Exception 呢?特此记录一下这样做的好处。
Exception
我们知道异常分为两类:检查异常CheckedException 和运行时异常RuntimeException。
CheckedException
Java认为Checked异常都是可以被处理的异常,所以Java程序必须显式的处理Checked异常,如果程序没有处理checked异常,程序在编译时候将发生错误。
我们比较熟悉的Checked异常有 :
java.lang.ClassNotFoundException
java.lang.NoSuchMetodException
java.io.IOException
RunTimeException
Runtime如除数是0和数组下标越界等,其产生频繁,处理麻烦,若显示申明或者捕获将会对程序的可读性和运行效率影响很大。所以由系统自动检测并将它们交给缺省的异常处理程序。当然如果你有处理要求也可以显示捕获它们。
我们比较熟悉的RumtimeException类的子类有:
java.lang.ArithmeticException
java.lang.ArrayStoreExcetpion
java.lang.ClassCastException
java.lang.IndexOutOfBoundsException
java.lang.NullPointerException
自定义异常
在框架中我自定了个异常,方便异常处理维护,代码如下:
1 |
|
自定义异常继承自 RuntimeException,这样有两个好处:
1.方法中抛出此自定义异常,调用此方法的方法不用显示地 throws 该异常。
2.Spring 事务回滚默认只支持 RuntimeException。
Spring 事务默认回滚规则
我们在使用Spring时候一般都知道事务在遇到异常的时候会回滚,岂不知Spring的事务默认只有在发生运行时异常即:RunTimeException时才会发生事务,如果一个方法抛出Exception或者Checked异常Spring的事务并不会回滚。
查看 Spring 注解@Transactional
源码:
1 | /** |
通过注释可以知道RollbackRuleAttribute
类是配置 Spring事务回滚规则的类,查看此类源码:
1 | public class RollbackRuleAttribute implements Serializable{ |
通过源码我们知道 Spring默认是只对 RuntimeException 进行回滚,这就要求我们自定义异常的时候,让其继承 RuntimeException,这样异常抛出时才会被Spring默认的事务回滚规则处理。
spring的原则之一就是基层异常就应该是非检查性异常. 原因如下:
- 基层异常通常来说是不可恢复的。
- 检查性异常将会降低异常层次结构的价值.如果底层异常是检查性的, 那么就需要在所有地方添加catch语句进行捕获。
如何改变 Spring 默认事务规则?
在@Transaction注解中定义noRollbackFor和RollbackFor指定某种异常是否回滚。
@Transaction(noRollbackFor=RuntimeException.class)
@Transaction(RollbackFor=Exception.class)
- Title: Spring事务默认回滚规则
- Author: 薛定谔的汪
- Created at : 2018-06-22 18:01:54
- Updated at : 2023-11-17 19:37:37
- Link: https://www.zhengyk.cn/2018/06/22/spring/Rollback-rule/
- License: This work is licensed under CC BY-NC-SA 4.0.