Spring中事务处理机制---RuntimeException()和Exception()

Spring中事务处理机制—RuntimeException()和Exception()

1. Java异常体系

Java异常体系结构图:

image-20220729090033176

1.1 Error和Exception

​ 在 Java 中,所有的异常都有一个共同的祖先 java.lang 包中的 Throwable 类。 Throwable 类 有两个重要的子类 Exception (异常)和 Error (错误)。 Exception 能被程序本身处理( try- catch ), Error 是无法处理的(只能尽量避免)。

  • Exception:程序本身可以处理的异常,可以通过 catch 来进行捕获。 Exception 又可以分为 受检查异常(必须处理) 和 不受检查异常(可以不处理)。

    • 受检查异常

    ​ Java 代码在编译过程中,如果受检查异常没有被 catch / throw 处理的话,就没办法通过编译 。

    除了 RuntimeException及其子类以外,其他的 Exception 类及其子类都属于检查异常 。受检查异常有: IO 相关的异常、 ClassNotFoundException 、 SQLException等。

    • 不受检查异常

    ​ Java 代码在编译过程中 ,我们即使不处理不受检查异常也可以正常通过编译。

    RuntimeException 及其子类都统称为非受检查异常,例如: NullPointExecrption 、 NumberFormatException (字符串转换为数字)、 ArrayIndexOutOfBoundsException (数组越界)、 ClassCastException (类型转换错误)、 ArithmeticException (算术错误)等。

  • Error:程序无法处理的错误,不可以通过catch进行捕获。这些错误发生时,Java 虚拟机(JVM)一般会选择线程终止。

1.2 运行时异常与非运行时异常

  1. 运行时异常(不检查异常)都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
  2. 非运行时异常(受检查异常)是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

2. 异常处理总结

​ Java异常处理方法有:抛出异常,捕捉异常。主要依赖于try、catch、finally、throw、throws五个关键字。

  1. try—catch。 try:它里面放置可能引发异常的代码,如果代码运行出现了错误,那么执行catch中的代码块
  2. throws:向外抛出异常,让之后一个接受到该异常的方法区处理
  3. finally:无论try指定的程序块是否抛出异常,finally中的代码一定会得到执行。
  4. throw:用于抛出一个实际的异常,抛出的时候是一个异常类的实例化对象,在异常处理中,try语句要捕获的是一个异常对象,那么此异常对象也可以自己抛出。
package methoud;
public class Demo01{
    public static void main(String args[]){
        try{
            throw new Exception("throw手动抛出一个异常") ; // 抛出异常的实例化对象
        }catch(Exception e){
            System.out.println(e) ;
        }
    }
};
  1. 用在方法签名中,用于声明该方法可能抛出的异常,表示此方法不处理异常,而交给方法调用处进行处理。
public class Demo02 {
	 public static void main(String args[]) throws Exception{
	        Math m = new Math() ;        // 实例化Math类对象
	        System.out.println("除法操作:" + m.div(10,0)) ;
	    }
}
class Math{
    public int div(int i,int j) throws Exception{    // 定义除法操作,如果有异常,则交给被调用处处理
        int temp = i / j ;  
        return temp ;
    }
};

3. Spring事务处理

​ **Spring事务默认只在发生未被捕获的RuntimeException()时才进行回滚。**但不是RuntimeException或其子类的异常不能够捕获,只是默认情况下不进行回滚。

​ 通过配置来捕获特定的异常并回滚 :

方式1

​ 在service层不使用try…catch或者在catch中最后加上throw new RuntimeException(),这样程序异常时aop才可以捕获异常并进行回滚。

​ 最终在service上层(如controller层、action层、view层)要继续捕获这个异常并处理。

方式2

在service层方法上进行配置,改变默认规则,方法如下 :

  1. 受检查异常也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)

  2. 不受检查异常不回滚:

    @Transactional(notRollbackFor=RunTimeException.class)

  3. 不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.*NOT_SUPPORTED*)

在整个方法运行前就不会开启事务还可以加上: @Transactional(propagation=Propagation.NOT_SUPPORTED, readOnly=true),这样就做成一个只读事务,并可以提高效率。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

St_up

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值