我之前一直质疑网传mysql innodb的RR隔离级别下,next-key lock解决了幻读这种说法的准确性。

这次理顺了。

例子准备:

场景一、select * from user

order sessionA sessionB 结果 解释
T1 start transaction;      
T2   start transaction;    
T3   select * from user; 成功

有三条

快照读

T4 insert into user (mobile_phone,age) values ('1234',121);   成功  
T5   select * from user; 成功

只有三条

因为是快照读,且事务A还没提交。

此处是MVCC避免了幻读

T6   select * from user where id = 1; 成功  
T7   select * from user where id = 3; 成功  
T8   select * from user lock in share mode; 等待 当前读,加共享锁,而事务A锁定了刚insert的id4
  commit;    

此时事务B的等待结束,T8的结果是有四条,看到了事务A的insert的内容

出现幻读

    select * from user; 成功

只有三条

因为是快照读。

此处是MVCC避免了幻读

    select * from user lock in share mode; 成功

有四条,看到了事务A的insert的内容

出现幻读

看一下next-key lock的含义:当sql语句按照范围查询非唯一索引列,并且有数据命中的时候会给索引加上临键锁,锁住命中索引项的前一个索引到命中索引项的后一个索引之间的一个左开右闭区间

该场景结论:

select *  from user 是快照读,是MVCC避免了幻读

select * from user lock in share mode,当前读,触发了幻读。

善意的理解,这种查询SQL并没有走非唯一索引,也不是范围查询,所以next-key lock并没有生效。

换句话说:准确的说,mysql innodb 的 RR隔离下,一样会出现幻读,next-key lock和MVCC只解决了部分幻读的场景。

场景二、select * from user where age >60 and age < 100

order sessionA sessionB 结果 解释
T1 start transaction;      
T2   start transaction;    
T3   select * from user where age >60 and age < 100; 成功

有2条

快照读

T4

insert into user (mobile_phone,age) values ('1234',121);

insert into user (mobile_phone,age) values ('1234',50);

insert into user (mobile_phone,age) values ('1234',101);

insert into user (mobile_phone,age) values ('1234',61);

insert into user (mobile_phone,age) values ('1234',91);

     
T5   select * from user where age >60 and age < 100 成功

有2条

快照读

T6   select * from user where id = 1;    
T7   select * from user where id = 3;    
T8   select * from user where age >60 and age < 100 lock in share mode; 等待 当前读,加共享锁,而事务A锁定了刚insert的id45678
  commit;    

此时事务B的等待结束,T8的结果是有四条,看到了事务A的insert的内容

出现幻读

    select * from user where age >60 and age < 100; 成功

只有三条

因为是快照读。

此处是MVCC避免了幻读

    select * from user where age >60 and age < 100 lock in share mode; 成功

有四条,看到了事务A的insert的内容

出现幻读

该场景结论同场景一一样

场景三、 select * from user where age >60 and age < 100 lock in share mode;

order sessionA sessionB 结果 解释
T1 start transaction;      
T2   start transaction;    
T3   select * from user where age >60 and age < 100 lock in share mode; 成功

有2条

此时加上了next-key lock age=0 到 aget=120

T4

insert into user (mobile_phone,age) values ('1234',121);

 

成功

 
    select * from user where age >60 and age < 100 lock in share mode;  

有2条

该区间内本来也只有2条

    select * from user where age >60 and age < 100;  

有2条

该区间内本来也只有2条

  insert into user (mobile_phone,age) values ('1234',0);   等待 因为T3加了next-key lock
  UPDATE user  set mobile_phone = '11111' WHERE age = 120;   等待 因为T3加了next-key lock
T5

insert into user (mobile_phone,age) values ('1234',50);

  等待

因为T3加了next-key lock

T7

insert into user (mobile_phone,age) values ('1234',61);

  等待 因为T3加了next-key lock
T8 insert into user (mobile_phone,age) values ('1234',91);   等待 因为T3加了next-key lock
    commit;  
       

事务A等待结束,insert成功

       

该场景结论:

用当前读,非唯一索引范围查询,会加next-key lock,另外一个事务在该区间不能再insert值需等next-key lock释放

该场景下的确是next-key lock避免了幻读

总结

MySQL Innodb RR隔离级别下能够解决幻读的场景及原因:

1.快照读,由MVCC解决幻读

2.当前读,只有在利用非唯一索引进行范围查询的时候,才会使用next-key lock,避免该范围内的幻读

【十四】MySQL Innodb RR隔离级别下到底是不是解决了幻读相关推荐

  1. MySQL在RR级别下到底有没有修复幻读

    微信搜索"coder-home"或扫一扫下面的二维码,关注公众号,第一时间了解更多干货分享,还有各类视频教程资源.扫描它,带走我 文章目录 背景 疑问点 分析 什么是快照读 开启事 ...

  2. RR隔离级别下通过next-key locks 避免幻影读

    ---恢复内容开始--- mysql innodb目前使用范围最广的两种隔离级别为RC和RR,RR修复了RC中所存在的不可重复读 READ COMMITED 不可重复读 在同一事务中两次查看的结果集不 ...

  3. InnoDB在RR隔离级别下解决幻读问题

    表象:快照读(非阻塞读)-伪MVCC 内在:next-key锁(行锁+gap锁) 当前读和快照读 当前读:select-lock in share mode(共享锁),select-for updat ...

  4. Mysql RR隔离级别下,当前事务的更新前后ReadView查询结果不一致

    先给个答案: 在可重复读(REPEATABLE READ)隔离级别下,当前事务是可以读取到当前事务修改的数据结果,这是通过 Read View 机制实现的. Read View 记录了事务开始时数据库 ...

  5. mysql trans begin_[原创]MySQL RR隔离级别下begin或start transaction开启事务后的可重复读?...

    Server version:         5.6.21-log MySQL Community Server (GPL) 前提提要: 我们知道MySQL的RR(repeatable read)隔 ...

  6. mysql innodb 默认隔离级别_MySQL Innodb 事务隔离级别

    在Mysql中,事务主要有四种隔离级别,今天我们主要是通过示例来比较下,四种隔离级别实际在应用中,会出现什么样的对应现象. Read uncommitted (未提交读) Read committed ...

  7. 浅析MySQL InnoDB的隔离级别

    前言 还是老规矩,首先提出两个待解决的问题: MySQL InnoDB存储引擎中事务的隔离级别有哪些? 对应隔离级别的实现机制是什么? 本文就将对上面这两个问题进行解答,分析事务的隔离级别以及相关锁机 ...

  8. mysql innodb隔离级别_浅析MySQL InnoDB的隔离级别

    本文就将对上面这两个问题进行解答,分析事务的隔离级别以及相关锁机制. 隔离性简介 隔离性主要是指数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的"独立"环境执行,意思 ...

  9. 事务的4种隔离级别,3大问题,脏读幻读不可重复读

    一.数据库事务隔离级别 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted .Read committed .Repeatable read .Serializable ,这四 ...

最新文章

  1. 顶配版阿里大佬面试笔记+300道硬核面试题,跪着啃完了。。。。
  2. .NET中的按需加载/延迟加载 LazyT
  3. 5G NGC — NWDAF 网络智能分析功能
  4. 学习笔记——itertools模块
  5. java中File的使用
  6. 简单使用Git和Github来管理自己的代码和读书笔记
  7. python爬虫安装错误与解决方式
  8. 兆观毫米波监护仪亮相CMEF 开创养老监护新时代
  9. 基于Android的智能家居手持终端系统开发 毕业论文-A
  10. java 常量池溢出_Java方法区和运行时常量池溢出问题分析(转)
  11. 用python爬取微信公众号文章
  12. FFmpeg教程(超级详细版)
  13. Java网络编程:TCP实现群聊功能代码
  14. 图片短链接生成器在线
  15. Tomcat中文乱码解决
  16. Apache ShenYu 快速开始
  17. js中break关键字的用法。
  18. STM32中的程序在RAM还是FLASH里运行?
  19. 【自用·记录】产品类补充学习·SaaS/visio/竞品分析SWOT用户体验五要素
  20. 合泰 HT66F2390 uart0与uart1 串口代码相互通信

热门文章

  1. 深入讲解VsCode各场景高级调试与使用技巧
  2. 软考——成本估算和成本预算的区别和联系(论文考点)
  3. android nfc settimeout,微信小程序API NFC·NfcA标签
  4. 10 个开源免费的电子商务平台
  5. vscode编译 不允许使用与号()。 运算符是为将来使用而保留的;请用双引号将与号引起来(““),以将其作为字符串的一部分传递
  6. PyTorch导入报错:ValueError: module functions cannot set METH_CLASS or METH_STATIC
  7. html+js 实现鼠标粒子拖尾效果其中调用underscore和jQuery库
  8. SpringBoot 读取Maven ProjectVersion
  9. ZHS16GBK字符集插入中文时报错ORA-01756
  10. iOS设备尺寸、像素对照表