zoukankan      html  css  js  c++  java
  • 事务分析(一) 事务回滚

    事务回滚分析 @Transaction rollbackfor


    1.@Transactional的rollbackfor默认回滚异常

    不设置rollbackfor时,默认遇到运行时异常(RuntimeException)才回滚事务,非运行时异常不会回滚

     2.只有@Transactional,运行时异常和非运行时异常回滚测试

    情景1:运行时异常(异常抛出) java.lang.ArithmeticException: / by zero  

    @Transactional
    public void test1(){
    userMapper.insert("LiLei",122);
    System.err.println(1/0);
    }

    运行结果: 事务回滚 org.springframework.transaction.interceptor.TransactionInterceptor.invoke ,数据没有插入到数据库

    情景2:运行时异常(异常捕获) java.lang.ArithmeticException: / by zero  

    @Transactional
    public void test1(){
        userMapper.insert("LiLei1",122);
        try {
            System.err.println(1/0);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    运行结果:事务未回滚,数据成功插入到数据库

    情景3:运行时异常(异常捕获再抛出)

    @Transactional
    public void test1(){
        userMapper.insert("LiLei11",122);
        try {
            System.err.println(1/0);
        } catch (ArithmeticException e) {
            e.printStackTrace();
            throw e;
        }
    }

    运行结果: 事务回滚,数据没有插入到数据库

    情景4:非运行时异常(异常抛出) java.lang.ClassNotFoundException: null 

    @Transactional
    public void test1() throws ClassNotFoundException {
        userMapper.insert("LiLei",122);
    throw new ClassNotFoundException();
    }

    运行结果:事务未回滚,数据成功插入到数据库

    情景5:非运行时异常(异常捕获) java.lang.ClassNotFoundException: null 

    @Transactional
    public void test1() {
        userMapper.insert("LiLi",122);
        try {
            throw new ClassNotFoundException();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    运行结果:事务未回滚,数据成功插入到数据库


     小结:

    @Transactional 未设置 rollbackfor 时,默认识别运行时异常 RunTimeException() ,非运行时异常不会回滚,且RunTimeException()被捕获时不会触发事务回滚.

    我们比较熟悉的RumtimeException类的子类有
    Java.lang.ArithmeticException
    Java.lang.ArrayStoreExcetpion
    Java.lang.ClassCastException
    Java.lang.IndexOutOfBoundsException
    Java.lang.NullPointerException
    
    

     3.指定rollbackfor=Exception.class回滚测试

    情景1:

    @Transactional(rollbackFor = Exception.class)
    public void test1(){
    userAdd2("Jobs",22);
    }
    public void userAdd2(String name,Integer age){
    userMapper.insert(name,age);
    try {
    throw new NullPointerException();
    } catch (NullPointerException e) {
    e.printStackTrace();
    }
    }

    运行结果:事务未回滚,数据成功录入

    情景2:

    @Transactional(rollbackFor = Exception.class)
    public void test1(){
    userAdd2("Jobs",22);
    }
    public void userAdd2(String name,Integer age){
    userMapper.insert(name,age);
    throw new NullPointerException();
    }

    运行结果:事务回滚,数据没有插入到数据库


    小结:

    这两个情景的测试结果很明显了,由步骤2的5个情景已经可以推测出结果

    4.@Transactional()的回滚失效分析

     情况1:上边提到的异常被捕获处理,且 外层方法添加了事务 

     情况2:外层方法没添加事务

    public void test1(){
    userAdd1("Jobs",22);
    }
    @Transactional
    public void userAdd1(String name,Integer age) {
    userMapper.insert(name,age);
    System.err.println(1/0);
    }

    运行结果:事务未回滚,数据成功插入到数据库

    原因分析:

     AOP 使用的是动态代理的机制,它会给类生成一个代理类,事务的相关操作都在代理类上完成。内部方式使用this调用方式时,使用的是实例调用,并没有通过代理类调用方法,所以会导致事务失效

    作者:往霄龙
    求其上者得其中,求其中者得其下
  • 相关阅读:
    走进JavaWeb技术世界8:浅析Tomcat9请求处理流程与启动部署过程
    走进JavaWeb技术世界7:Tomcat和其他WEB容器的区别
    走进JavaWeb技术世界6:Tomcat5总体架构剖析
    走进JavaWeb技术世界5:初探Tomcat的HTTP请求过程
    走进JavaWeb技术世界4:Servlet 工作原理详解
    走进JavaWeb技术世界3:JDBC的进化与连接池技术
    [转]115个Java面试题和答案——终极列表(下)
    [转]115个Java面试题和答案——终极列表(上)
    [转]Spring MVC 4常用的那些注解
    [转]spring4.x注解概述
  • 原文地址:https://www.cnblogs.com/JQKA/p/11646743.html
Copyright © 2011-2022 走看看