• mysql 事务 Repeatable Read


    在这之前介绍了mysql隔离级别最低的一种事务级别 Read Uncommitted,还介绍了可能出现不可重复读(Non Repeatable Read)的事务隔离级别 Read Committed,今天介绍一下相对更高的mysql事务隔离级别Repeatable Read。

    在Repeatable Read隔离级别下,一个事务可能会遇到幻读(Phantom Read)的问题。

    幻读是指,在一个事务中,第一次查询某条记录,发现没有,但是,当试图更新这条不存在的记录时,竟然能成功,并且,再次读取同一条记录,它就神奇地出现了。

    我们来测试一下,首先准备一个有数据的student表:

    然后,分别开启两个MySQL客户端连接,按顺序依次执行事务A和事务B:

    时刻事务A事务B
    1SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
    2BEGIN;BEGIN;
    3SELECT * FROM student WHERE id = 4;
    4INSERT INTO student (id, name) VALUES (4, '张三');
    5COMMIT;
    6SELECT * FROM student WHERE id = 4;
    7UPDATE student SET name = '李四' WHERE id = 4;
    8SELECT * FROM student WHERE id = 4;
    9COMMIT;

     事务B在第3步第一次读取id=4的记录时,读到的记录为空,说明不存在id=4的记录。随后,事务A在第4步插入了一条id=4的记录并提交。事务B在第6步再次读取id=4的记录时,读到的记录仍然为空,但是,事务B在第7步试图更新这条不存在的记录时,竟然成功了,并且,事务B在第8步再次读取id=4的记录时,记录出现了。

    可见,幻读就是没有读到的记录,以为不存在,但其实是可以更新成功的,并且,更新成功后,再次读取,就出现了。

      比起Read UncommittedRead Committed ,Repeatable Read隔离级别相对较高,不会出现 脏读和不可重复读的情况,但是会出现幻读的情况。

    总结一下就是:

    • 脏读:读到别的事务没有提交的数据。
    • 不可重复读:先前读取的数据,被别的事务改变了,再读就跟原来不一样了。
    • 幻读:一个事务插入了某条数据,另一个事务去读插入的那条数据的时候发现没有,更新这条记录的时候又成功了,再次查询这条记录就出现了。

    脏读是因为在读是时候没有加共享锁,不可重复读是因为没有遵循两阶段加锁,即在释放锁之后不能申请锁,所有锁的申请必须在释放之前。幻读可能是因为锁的颗粒度问题。如果是严格按照两阶段锁的模型,即使读取不存在的元素,也要将该元素上锁,如果是这样的话,那insert语句会失败,也就不会有幻读的问题。

  • 相关阅读:
    java中的线程如何理解——精简
    从原理到代码实践 | pytorch损失函数
    【无标题】
    Neutron — 安全组
    《nginx》三、nginx负载均衡
    将 mixamo 中的动画重定向到 UE 的小白人中
    ICV:《中美量子产业融资比较分析》
    【Linux】在Ubuntu下安装Zotero
    echarts实现柱图的下钻功能
    springboot实现热部署
  • 原文地址:https://blog.csdn.net/lwpoor123/article/details/126765647