zoukankan      html  css  js  c++  java
  • Read Committed 为什么不能防止不可重复度现象

    我们都知道MySQL 数组库有四大事务隔离级别,分别是未提交读(Read Uncommitted)、提交读(Read Committed)、可重复度(Repeatable Read)、可串行化(SERIALIZABLE).

    其中每个隔离级别有不同的特性

    未提交读可能会导致脏读,不可重复度和幻读问题。

    提交读因为只能读取已经提交的数据,所以可以避免脏读,但是不保证事务重新读的时候能读到相同的数据,因为在每次数据读完之后其他事务可以修改刚才读到的数据,所以不能避免不可重复读和幻读现象,

    可重复读则可以避免脏读和不可重复度现象,但是不能避免幻读现象

    可串行化则能同时避免脏读、不可重复读和幻读现象。

    相信大家对上面的四个隔离级别的特征都耳熟能详,但是今天我突然发现一个问题,为什么提交读不能避免不可重复现象,既然读的事务还没有提交,为什么其他事务可以修改刚才读到的数据?既然一个字段或一条记录已经被一个事务的读锁占据,为什么还会被另一个事务的写锁获取到?

    先看一个提交读的隔离级别下发生不可重复度读现象的一个例子

    ① 打开命令客户端A,将这个客户端的隔离级别设置为提交读(Read Committed),然后开启事务,读取account表中的数据

    第一次读取account表的数据,money 为1000.00,不提交事务

     ② 开启命令行客户端B, 同样设置事务的隔离级别为提交读,开启事务,对account 表中tom的 money 进行修改,不提交事务

    客户端开启事务后B修改表数据,但是不提交事务

     ③ 客户端A 再次读取表中数据,因为客户端B的事务还未提交,所以客户端A读取不到客户端B修改后的值,读取到的数据仍是上一次事务提交后的值1000, 这就避免了脏读

    ④ 客户端B提交事务

    ⑤ 客户端 A 再次查看,读取到 2000, 发现和上一次读取的money值不一样,同一个事务中前后两次读取到的数据不一样,发生了不可重复度现象

     

      通过上面这个例子,可以看到提交读的隔离级别下,确实不能避免不可重复读现象,现在的疑问是,明明客户端A的事务1已经先对记录加了读锁,为什么客户端B的事务2可以修改记录的数据呢?按我们常规的想法不应该是读锁和写锁互斥吗?

     原因:

    MySQL 中的提交读和可重复读两个隔离级别是使用多版本并发控制 MVCC 来实现的,而不是通过添加读写锁来实现的,如果通过读写锁来实现隔离级别的话,只有读读可以并发,读写,写读,写写都不能并发,这样数据库的并发度太低了,所以一般不通过加读写锁来实现隔离级别。而如果使用 MVCC 来实现 提交读和可重复读两个隔离级别的话则可以在读的时候不加锁,读写和写读可以同时进行,只有写写需要阻塞,这样就极大地提高了并发度。

    MVCC 机制会记录每行数据的历史版本,通过可见性算法、undo 日志以及 read view 控制每个读操作所读取的行数据历史版本,

    Repeatable Read 在事务发生第一次读的时候选定所要读取的数据行的版本,整个事务都读取这一个版本的数据行,所以可以重复读,每次读取的数据都一致。

    Read Committed 在事务中每次读操作都是读取最新的行数据版本,而这最新的数据行版本很可能是某个事务进行了修改操作后提交的,所以可能会发生多次读取同一行数据,但是前后读取的数据不一致的情况。这就是不可重复读现象,所以提交读不能避免不可重复度现象。

    想要详细了解MVCC是如何实现事务隔离的,可以阅读这篇博客,MySQL中MVCC的正确打开方式(源码佐证),写的非常好,强力推荐。

    文章参考:

    不可重复读(read-committed)读已提交例子

    mysql事务之提交读(Read Committed)

  • 相关阅读:
    C项目实践--贪吃蛇(2)
    Dos下同时执行多条命令简化操作
    C语言进入界面编程准备篇
    C项目实践--图书管理系统(4)
    C项目实践--图书管理系统(3)
    C项目实践--图书管理系统(1)
    C项目实践--图书管理系统(2)
    bzoj2302: [HAOI2011]Problem c
    bzoj3545: [ONTAK2010]Peaks
    loj#2537. 「PKUWC2018」Minimax
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/12721152.html
Copyright © 2011-2022 走看看