• 探讨MySql RR事务隔离级别


    探讨MySql RR事务隔离级别

    明白一些东西

    RR解决了什么?

    RR解决了脏读的问题(保证了在同一个事务下,多次读取同样的数据的结果是一致的),最大功臣就是MVCC机制。但是这也导致RR级别出现的幻读问题,在特定情况下,还是无法彻底解决,本文指在探讨幻读产生的原因,方便之后在开发过程中,避免可能导致幻读情况发生的操作。

    其他事务隔离级别暂不探究,探究使用较多的RR。

    幻读

    RR幻读主要源头

    MySQL 使用了多版本并发控制(MVCC)来处理并发事务。MVCC 允许事务在读取数据时不被其他事务的更新所干扰,但在插入或更新数据时,会进行行级锁的加锁操作,以保证数据的一致性。然而,由于行级锁只能锁定已存在的数据行,无法锁定不存在的数据行。

    幻读:假设A事务在读取D范围的记录时,B事务又在D范围内插入新的记录,那么A事务再次读取D范围的记录时,就会出现"幻行"。这是其中一种情况。

    说一下MVCC

    MVCC只在RR(可重复读),RC(读已提交,不可重复读,一个事务从开启到提交,做的修改操作对其他事务都是不可见的)下工作,RU(读未提交)和串行化下不工作。RU总是读取最新数据,串行化对读取行都加锁。

    很多数据库都有实现自己的MVCC,实现机制各有不同;Mysql的MVCC,是通过保存数据在某个时间点的快照来实现的,保证不管事务执行多久,看到的数据都是一致的,类似与时间链,事务开始时间不同,看到的数据也可能不一样。

    InnoDB的MVCC,是通过在每行记录后面保存两个隐藏列实现。一个列是行创建时间,一个是行删除时间,

    当然这里的时间指的是系统指定的版本号。每开启一个新事务,系统版本号都会递增,事务开始时刻的系统版本号作为事务的版本号,用来和查询的行记录的版本号进行比较。使大多数读操作都可以不用加锁

    如何比较:

    SELECT:

    ​ 条件1:查找小于等于当前事务版本号的数据行(早于当前事务创建时间),这样可以保证读取到的行,是已经存在或者事务自己插入或者修改过的。(这里的插入,修改往后面看)

    ​ 条件2:行的删除版本要么没有定义,要么大于当前事务版本号,这样可以确保读取到的行,在事务开始前没有被删除。

    INSERT:

    ​ 为新插入的行,保存当前的系统版本号作为行版本号;这里就对应上面的SELECT了。

    DELETE:

    ​ 删除的行,保存当前的系统版本号作为行删除版本。

    UPDATE:

    ​ 更新时,保存当前系统版本号作为行版本号,行删除版本。

    幻读发生的可能场景
    1. 插入新数据:一个事务在可重复读隔离级别下执行了一个查询,返回一组数据。然后另一个事务插入了符合该查询条件的新数据,并提交了事务。当第一个事务再次执行相同的查询时,会发现多了一条之前不存在的数据,从而产生幻读。
    2. 删除已有数据:一个事务在可重复读隔离级别下执行了一个查询,返回一组数据。然后另一个事务删除了其中的一些数据,并提交了事务。当第一个事务再次执行相同的查询时,会发现之前查询到的数据中有一部分已经被删除了,从而产生幻读。
    3. 修改已有数据:一个事务在可重复读隔离级别下执行了一个查询,返回一组数据。然后另一个事务修改了其中的一些数据,并提交了事务。当第一个事务再次执行相同的查询时,会发现之前查询到的数据发生了变化,从而产生幻读。
    间隙锁(锁住一定范围的数据)

    间隙锁(Gap Lock)是MySQL中的一种行级锁,用于解决幻读问题。它通常与可重复读或更高的隔离级别一起使用。

    间隙锁的作用是锁定一个范围的键值之间的间隙(即不存在的键值范围),防止其他事务在该范围内插入新的数据,从而避免了幻读问题的发生。

    事务A:

    START TRANSACTION;
    SELECT * FROM table WHERE column > 10 AND column < 20 FOR UPDATE;
    
    • 1
    • 2

    事务B:

    START TRANSACTION;
    INSERT INTO table (column) VALUES (15);
    COMMIT;
    
    • 1
    • 2
    • 3

    在事务A执行SELECT语句时,它会获取一个范围锁,锁定了 column > 10 and column < 20 的间隙。因此,事务B在该范围内插入数据时会被阻塞,直到事务A释放间隙锁。

    幻读能彻底解决吗

    .....待补充
    我觉得不行…知道啥原因引起的,就可能规避这种风险,造房子的,你还要去生产水泥跟砖头吗?
  • 相关阅读:
    乐优商城(一)介绍和项目搭建
    C++:VS2019 Windows SDK 10损坏重装
    数学建模-多目标规划算法(美赛建模)
    通过循环按行顺序为一个5×5的二维数组a赋1到25的自然数,然后输出该数组的左下半三角的元素。
    R语言内连接两个dataframe数据(Inner join)
    [C++] 小游戏 斗破苍穹 2.2.1至2.11.5全部版本(上) zty出品
    洛谷P5094 MooFest G 加强版
    读透业务安全白皮书——未来四大趋势
    源码构建LAMP环境-2
    异常~~~
  • 原文地址:https://blog.csdn.net/weixin_44313584/article/details/133721817