• 数据库事务——事务隔离级别


    数据库的事务隔离级别

    SQL 标准定义了四种隔离级别,这四种隔离级别分别是:

    • 读未提交(READ UNCOMMITTED);
    • 读提交 (READ COMMITTED);
    • 可重复读 (REPEATABLE READ);
    • 串行化 (SERIALIZABLE)

    事务隔离是为了解决脏读、不可重复读、幻读问题,下表展示了 4 种隔离级别对这三个问题的解决程度:

    隔离级别脏读不可重复读幻读
    READ UNCOMMITTED可能可能可能
    READ COMMITTED不可能可能可能
    REPEATABLE READ不可能不可能可能
    SERIALIZABLE不可能不可能不可能

    上述4种隔离级别MySQL都支持,并且InnoDB存储引擎默认的支持隔离级别是可重复读(REPEATABLE READ),但是与标准SQL不同的是,InnoDB存储引擎在REPEATABLE READ事务隔离级别下,使用Next-Key Lock的锁算法,因此避免了幻读的产生。所以,InnoDB存储引擎在默认的事务隔离级别下已经能完全保证事务的隔离性要求,即达到SQL标准的SERIALIZABLE隔离级别

    并发情况下,读操作可能存在的三类问题:

    1. 脏读:当前事务(A)中可以读到其他事务(B)未提交的数据(脏数据),这种现象是脏读。

    2. 不可重复读:在事务A中先后两次读取同一个数据,两次读取的结果不一样,这种现象称为不可重复读。

      脏读与不可重复读的区别在于:前者读到的是其他事务未提交的数据,后者读到的是其他事务已提交的数据。

    3. 幻读:在事务A中按照某个条件先后两次查询数据库,两次查询结果的条数不同,这种现象称为幻读。

      不可重复读与幻读的区别可以通俗的理解为:前者是数据变了,后者是数据的行数变了。

    MySQL的事务隔离级别的实现

    InnoDB支持四种隔离级别,每种级别解决掉的问题如下表:

    脏读不可重复读幻读幻读
    READ UNCOMMITTEDYYY
    READ COMMITTEDNYY
    REPEATABLE READ(默认)NNN
    SERIALIZABLENNN

    这四种隔离级别的实现机制如下:

    1. READ UNCOMMITTED & READ COMMITTED:

    通过Record Lock算法实现了行锁,但READ UNCOMMITTED允许读取未提交数据,所以存在脏读问题。

    而READ COMMITTED允许读取提交数据,所以不存在脏读问题,但存在不可重复读问题。

    2. REPEATABLE READ:

    使用Next-Key Lock算法实现了行锁,并且不允许读取已提交的数据,所以解决了不可重复读的问题。另外,该算法包含了间隙锁,会锁定一个范围,因此也解决了幻读的问题。

    3. SERIALIZABLE:

    对每个SELECT语句后自动加上LOCK IN SHARE MODE,即为每个读取操作加一个共享锁。因此在这个事务隔离级别下,读占用了锁,对一致性的非锁定读不再予以支持。

    MySQL事务小细节

    事务可以嵌套吗?

    可以,因为嵌套事务也是众多事务分类中的一种,它是一个层次结构框架。有一个顶层事务控制着各个层次的事务,顶层事务之下嵌套的事务被称为子事务,它控制每一个局部的变换。

    需要注意的是,MySQL数据库不支持嵌套事务

    如何实现可重复读?如何解决幻读问题?

    MySQL的InnoDB引擎,在默认的REPEATABLE READ的隔离级别下,实现了可重复读,同时也解决了幻读问题。它使用Next-Key Lock算法实现了行锁,并且不允许读取已提交的数据,所以解决了不可重复读的问题。另外,该算法包含了间隙锁,会锁定一个范围,因此也解决了幻读的问题

    MySQL事务的回滚

    在MySQL默认的配置下,事务都是自动提交和回滚的。当显示地开启一个事务时,可以使用ROLLBACK语句进行回滚。

    该语句有两种用法:

    • ROLLBACK:要使用这个语句的最简形式,只需发出ROLLBACK。同样地,也可以写为ROLLBACK WORK,但是二者几乎是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。

    • ROLLBACK TO [SAVEPOINT] identifier :这个语句与SAVEPOINT命令一起使用。可以把事务回滚到标记点,而不回滚在此标记点之前的任何工作

  • 相关阅读:
    Android Unable to determine activity name
    Flask笔记二之blueprint和session介绍
    【iOS】-- 内存五大分区
    取消本次commit,git远程和本地同步,SourceTree分支合并
    深圳必去的50个免费景点 景色绝美
    年过中年危机,如果我再年轻十岁我会每天花几小时这样学习Java
    做强礼品经济韧性与活力,金秋10月第30届深圳礼品展来袭!
    Linux 进程控制
    【小余送书第二期】《MLOps工程实践:工具、技术与企业级应用》参与活动,即有机会中奖哦!!!祝各位铁铁们双节快乐!
    MATLAB 嵌套switch语句||MATLAB while循环
  • 原文地址:https://blog.csdn.net/weixin_45525272/article/details/126491334