• 事务的隔离级别、事务不生效的场景


    一、事务的隔离级别

    1、读未提交Read Uncommited:事务还没提交的时候,修改的数据就让别的事务给读到了----脏读

    2、读已提交Read Commited:事务A查询一个数据值是1,过了段时间,事务B把这个数据修改了还提交了,此时事务A再次查询这个数据值变为2了

    这是不可重复读,一个事务内对一个数据两次读,可能会读到不一样的值;

    3、可重复读Read Repeatable:事务A在执行过程中,读某个数据的值,无论读多少次都是1,就算过程中事务B将这个数据的值修改并提交了,事务A读到的还是自己事务开始时这个数据的值。

    4、幻读:幻读针对的是插入。

    某事务将所有记录行的某字段改为了2,结果此时另外一个事务插入了一条数据,该字段默认值是1,突然发现有条数据的值是1,以为产生幻觉了

    解决幻读需要锁表

    5、串行化:解决幻读就要使用串行化级别的隔离级别,所有事务串行起来,不允许多个事务并行操作

    MYSQL默认隔离级别是可重复读Read Repeatable,就是说每个事务都会开启自己要操作的数据的快照,读的都是快照数据,多次读结果一样;

    MYSQL通过MVCC多版本并发控制(multi-version concurrency control)  机制来实现

    二、事务不生效的场景

    1.private、final、static方法,事务不生效,入口方法必须是public ,spring的AOp特性决定的,spring认为private自己用的方法应该自己控制,不应该用事务切进去

    2、Spring的事务管理默认只对出现运行期异常(java.lang.RuntimeException及其子类)进行回滚(至于为什么spring要这么设计:因为spring认为Checked的异常属于业务的,coder需要给出解决方案而不应该直接扔该框架)

    3.同类调用不生效(service方法中调用本类中的另一个方法,事务没有生效):

    同一个类中一个无事务的方法调用另一个有事务的方法,事务是不会起作用

    4.如果使用的是rollbakfor的默认,已检查的异常(所有派生自Error和RuntimeException的类,都是未检查异常.其余的是已检查异常, 比如nullPointException是未检查的,IllegalAccessException 是已检查的)不回滚, 可设为rollbackFor={Exception.class}

    5.最好不要把@trasaction注解到接口上:

    在接口上使用 @Transactional 注解,只能当你设置了基于接口的代理时它才生效。因为注解是 不能继承 的,这就意味着如果正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装。

    6、确认你的类是否被代理了(因为spring的事务实现原理为AOP,只有通过代理对象调用方法才能被拦截,事务才能生效

    7、确保你的业务和事务入口在同一个线程里,否则事务也是不生效的

  • 相关阅读:
    (黑马十次方项目day06)@ConfigurationProperties报错的解决方式
    (黑马十次方项目day04)An attempt was made to call a method that does not exist. The attempt was made from the following location:
    (黑马十次方项目day02)使用map接收form表单的参数
    (黑马十次方项目day02)IDEA在方法之间添加分隔符及开启Run Dashboard管理
    (黑马十次方项目day01)spring-boot-starter-parent 包maven依赖报错
    (黑马十次方项目day01)从PDF文件中复制代码到pom文件中project报错
    ER图学习
    java 8 函数式库Vavr功能
    Guava Cache
    UML学习
  • 原文地址:https://www.cnblogs.com/blackdd/p/12481851.html
Copyright © 2020-2023  润新知