【十四】MySQL Innodb RR隔离级别下到底是不是解决了幻读
我之前一直质疑网传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隔离级别下到底是不是解决了幻读相关推荐
- MySQL在RR级别下到底有没有修复幻读
微信搜索"coder-home"或扫一扫下面的二维码,关注公众号,第一时间了解更多干货分享,还有各类视频教程资源.扫描它,带走我 文章目录 背景 疑问点 分析 什么是快照读 开启事 ...
- RR隔离级别下通过next-key locks 避免幻影读
---恢复内容开始--- mysql innodb目前使用范围最广的两种隔离级别为RC和RR,RR修复了RC中所存在的不可重复读 READ COMMITED 不可重复读 在同一事务中两次查看的结果集不 ...
- InnoDB在RR隔离级别下解决幻读问题
表象:快照读(非阻塞读)-伪MVCC 内在:next-key锁(行锁+gap锁) 当前读和快照读 当前读:select-lock in share mode(共享锁),select-for updat ...
- Mysql RR隔离级别下,当前事务的更新前后ReadView查询结果不一致
先给个答案: 在可重复读(REPEATABLE READ)隔离级别下,当前事务是可以读取到当前事务修改的数据结果,这是通过 Read View 机制实现的. Read View 记录了事务开始时数据库 ...
- mysql trans begin_[原创]MySQL RR隔离级别下begin或start transaction开启事务后的可重复读?...
Server version: 5.6.21-log MySQL Community Server (GPL) 前提提要: 我们知道MySQL的RR(repeatable read)隔 ...
- mysql innodb 默认隔离级别_MySQL Innodb 事务隔离级别
在Mysql中,事务主要有四种隔离级别,今天我们主要是通过示例来比较下,四种隔离级别实际在应用中,会出现什么样的对应现象. Read uncommitted (未提交读) Read committed ...
- 浅析MySQL InnoDB的隔离级别
前言 还是老规矩,首先提出两个待解决的问题: MySQL InnoDB存储引擎中事务的隔离级别有哪些? 对应隔离级别的实现机制是什么? 本文就将对上面这两个问题进行解答,分析事务的隔离级别以及相关锁机 ...
- mysql innodb隔离级别_浅析MySQL InnoDB的隔离级别
本文就将对上面这两个问题进行解答,分析事务的隔离级别以及相关锁机制. 隔离性简介 隔离性主要是指数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的"独立"环境执行,意思 ...
- 事务的4种隔离级别,3大问题,脏读幻读不可重复读
一.数据库事务隔离级别 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted .Read committed .Repeatable read .Serializable ,这四 ...
最新文章
- 顶配版阿里大佬面试笔记+300道硬核面试题,跪着啃完了。。。。
- .NET中的按需加载/延迟加载 LazyT
- 5G NGC — NWDAF 网络智能分析功能
- 学习笔记——itertools模块
- java中File的使用
- 简单使用Git和Github来管理自己的代码和读书笔记
- python爬虫安装错误与解决方式
- 兆观毫米波监护仪亮相CMEF 开创养老监护新时代
- 基于Android的智能家居手持终端系统开发 毕业论文-A
- java 常量池溢出_Java方法区和运行时常量池溢出问题分析(转)
- 用python爬取微信公众号文章
- FFmpeg教程(超级详细版)
- Java网络编程:TCP实现群聊功能代码
- 图片短链接生成器在线
- Tomcat中文乱码解决
- Apache ShenYu 快速开始
- js中break关键字的用法。
- STM32中的程序在RAM还是FLASH里运行?
- 【自用·记录】产品类补充学习·SaaS/visio/竞品分析SWOT用户体验五要素
- 合泰 HT66F2390 uart0与uart1 串口代码相互通信
热门文章
- 深入讲解VsCode各场景高级调试与使用技巧
- 软考——成本估算和成本预算的区别和联系(论文考点)
- android nfc settimeout,微信小程序API NFC·NfcA标签
- 10 个开源免费的电子商务平台
- vscode编译 不允许使用与号()。 运算符是为将来使用而保留的;请用双引号将与号引起来(““),以将其作为字符串的一部分传递
- PyTorch导入报错:ValueError: module functions cannot set METH_CLASS or METH_STATIC
- html+js 实现鼠标粒子拖尾效果其中调用underscore和jQuery库
- SpringBoot 读取Maven ProjectVersion
- ZHS16GBK字符集插入中文时报错ORA-01756
- iOS设备尺寸、像素对照表