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调用方式时,使用的是实例调用,并没有通过代理类调用方法,所以会导致事务失效

    作者:往霄龙
    求其上者得其中,求其中者得其下
  • 相关阅读:
    [转]CSS实现三角形的方法
    border:none 与border:0的区别
    jQuery选择器总结
    [转]利用CSS、JavaScript及Ajax实现图片预加载的三大方法
    [转]Javascript实现图片的预加载的完整实现
    [转]Javascript实现图片的预加载
    [转]资源预加载
    [转]css,javascript的预加载
    [转]预加载资源研究
    [转]移动WEB开发常用技巧
  • 原文地址:https://www.cnblogs.com/JQKA/p/11646743.html
Copyright © 2011-2022 走看看