zoukankan      html  css  js  c++  java
  • 【事务回滚与注解@Transactional 的测试demo】

    在项目中,@Transactional(rollbackFor=Exception.class),如果类加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚。

    在@Transactional注解中如果不配置rollbackFor属性,那么事物只会在遇到RuntimeException的时候才会回滚,加上rollbackFor=Exception.class,可以让事物在遇到非运行时异常时也回滚

    默认spring事务只在发生未被捕获的 RuntimeExcetpion 时才回滚。也可以说spring会对unchecked异常进行事务回滚;如果是checked异常则不回滚。将派生于Error或者RuntimeException的异常称为unchecked异常,所有其他的异常成为checked异常。

    我是不是可以理解为 不加注解,发生空指针而不捕获时会发生回滚?(对不对需要进行下面验证)

     

    PS: @Transactional注解 应当应用于service层实现类或实现类中的public方法上,且如果为只读方法无需添加注解。

    PSS:着重测试注解属性:rollbackFor :用于指定能够触发事务回滚的异常类型,可以指定多个异常类型,常见的runtime异常:空指针异常,数组越界异常

     

    现将进行测试,测试的控制变量如下:

      1.添加注解@Transactional(rollbackFor = Exception.class)

      2.添加注解@Transactional(norollbackFor = Exception.class)

      3.捕获 runtime 异常

      4.不捕获 runtime 异常

      

     好了,开测:

      测试用例1:不添加@Transactional注解,测试异常为空指针异常,而捕获的是runtime异常,结果是 无回滚,无异常抛出,数据顺利更新。

       测试用例2:不添加@Transactional注解,测试异常为空指针异常,而捕获的是数组越界异常,结果是 无回滚,抛出空指针异常,数据可顺利更新。

      测试用例3:和测试用例2类似,但没有使用try-catch去捕获runtime异常,结果依旧是 没有回滚。

       测试用例4:添加@Transactional(rollbackFor = NullPointerException.class)注解,指定空指针类型异常,测试异常为空指针异常,而捕获的是数组越界异常,结果是 发生回滚, 数据无更新。

        测试用例5:添加@Transactional(rollbackFor = NullPointerException.class)注解,测试异常为空指针异常,而捕获的是Exception异常(包含空指针异常),结果是 不发生回滚, 数据有更新。

     

         测试用例6:添加@Transactional(norollbackFor = NullPointerException.class)注解,测试异常为空指针异常,而捕获的ArrayIndexOutOfBoundsException

    异常(包含空指针异常),结果是 不发生回滚, 数据有更新。

     好了,以上列举了6种情况,总结如下:

      1.当没有配置注解@Transactional时,spring默认是不开启事物管理的。

      2.配置注解后,回滚的前提是,try-catch捕获情况符合注解中参数的规范,且方法用public修饰,要求mysql数据库的引擎是InnoDB,因为只有InnoDB才是支持事务的( 可以用show variables like 'default_storage_engine'语句来查看数据库当前引擎)

      3.配置注解后,如果catch中捕获到了对应异常,那么即使配置注解也不会发生回滚。

      3.再次声明,unchecked exception–编译器不要求强制处置的异常,可以理解为 java.lang.RuntimeException类及它的子类都是非受查异常,如错误的类型转换异常:ClassCastException,下标越界异常:ArrayIndexOutOfBoundsException,空指针访问异常:NullPointerException,除零溢出异常:ArithmeticException等;

      4.注解属性:

    附:

    参考博客:https://www.cnblogs.com/clwydjgs/p/9317849.html

    spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获runtimeexception的异常,但可以通过配置来捕获特定的异常并回滚。

    在Spring FrameWork 的事务框架中推荐的事务回滚方法是,在当前执行的事务上下文中抛出一个异常。如果异常未被处理,当抛出异常调用堆栈的时候,Spring FrameWork 的事务框架代码将捕获任何未处理的异常,然后并决定是否将此事务标记为回滚。

    在默认配置中,Spring FrameWork 的事务框架代码只会将出现runtime, unchecked 异常的事务标记为回滚;也就是说事务中抛出的异常时RuntimeException或者是其子类,这样事务才会回滚(默认情况下Error也会导致事务回滚)。在默认配置的情况下,所有的 checked 异常都不会引起事务回滚。

    注:Unchecked Exception包括Error与RuntimeException. RuntimeException的所有子类也都属于此类。另一类就是checked Exception。

    Spring的事务管理默认是针对unchecked exception回滚,也就是默认对Error异常和RuntimeException异常以及其子类进行事务回滚,且必须对抛出异常,若使用try-catch对其异常捕获则不会进行回滚!(Error异常和RuntimeException异常抛出时不需要方法调用throws或try-catch语句);
    checked异常,checked异常必须由try-catch语句包含或者由方法throws抛出,且事务默认对checked异常不进行回滚。
    在service层若不加@Transactional则spring默认是不开启事物管理的。

    从源码来看,默认回滚的 类型确实是runtime异常和error

     

  • 相关阅读:
    python中的编码问题
    CVPR2018 Tutorial 之 Visual Recognition and Beyond
    hdu 1376 Octal Fractions
    hdu 1329 Hanoi Tower Troubles Again!
    hdu 1309 Loansome Car Buyer
    hdu 1333 Smith Numbers
    hdu 1288 Hat's Tea
    hdu 1284 钱币兑换问题
    hdu 1275 两车追及或相遇问题
    hdu 1270 小希的数表
  • 原文地址:https://www.cnblogs.com/dabuliu/p/15705752.html
Copyright © 2011-2022 走看看