RR隔离级别下通过next-key locks 避免幻影读
---恢复内容开始---
mysql innodb目前使用范围最广的两种隔离级别为RC和RR,RR修复了RC中所存在的不可重复读
READ COMMITED
不可重复读
在同一事务中两次查看的结果集不同,如下session1的查看结果集受session2提交的事物影响
05:47:35[test](;)> select @@tx_isolation;+----------------+| @@tx_isolation |+----------------+| READ-COMMITTED |+----------------+ session1 03:28:11[test](;)> begin; Query OK, 0 rows affected (0.00 sec) 03:28:21[test](;)> select * from t1; Empty set (0.01 sec) session2 03:28:27[test](;)> insert into t1 values(1,1,1,1,1); Query OK, 1 row affected (0.00 sec) 03:29:25[test](;)> select * from t1; +----+------+------+------+------+ | id | col1 | col2 | col3 | col4 | +----+------+------+------+------+ | 1 | 1 | 1 | 1 | 1 | +----+------+------+------+------+ 1 row in set (0.00 sec)
幻影读(Phantom Rows)
什么是幻影读
同一事务保证了一致性读后,查询时对提交的事务是不可见的,但是变更的时候是可见的,所以就有可能引发幻影读
为什么会导致幻影读
对于update或delete操作(可以使用SELECT
with FOR UPDATE
or LOCK IN SHARE MODE
来进行模拟),innodb只加记录锁(满足条件索引记录)而不是gap锁,gap锁只用于外键约束和duplicate key的检查,所以允许另一事务在锁定的记录旁边自由插入新记录
如col2上有索引,在满足col2>5的条件索引上加索引(对于RC,只在col2为10的索引记录上加X lock),所以在另一会话总插入col2 为非10的记录则会成功
set tx_isolation='read-committed' ; session 1 07:46:16[test](;)> begin; Query OK, 0 rows affected (0.00 sec) 07:46:20[test](;)> select * from t1 where col2>5 for update; +----+------+------+------+------+ | id | col1 | col2 | col3 | col4 | +----+------+------+------+------+ | 2 | 2 | 10 | 2 | 2 | +----+------+------+------+------+ 1 row in set (0.00 sec) 07:44:48[test](;)> begin; Query OK, 0 rows affected (0.00 sec) 07:46:36[test](;)> insert into t1 values(3,3,6,3,3); Query OK, 1 row affected (0.00 sec) 07:46:38[test](;)> commit; Query OK, 0 rows affected (0.10 sec) 07:46:31[test](;)> select * from t1 where col2>5; +----+------+------+------+------+ | id | col1 | col2 | col3 | col4 | +----+------+------+------+------+ | 3 | 3 | 6 | 3 | 3 | | 2 | 2 | 10 | 2 | 2 | +----+------+------+------+------+ 2 rows in set (0.00 sec)
若col2上无索引,也会是同样的结果现象,如果条件字段上无索引,innodb会先将所有行都加上锁,然后返回给server层根据条件筛选,满足条件则释放行锁,不满足条件则不释放
REPEATABLE READ
如何实现可重复读
事物开始时记录当前的快照版本,事务期间读取的都是事务开始时的快照版本
如何避免幻影读
通过 next-key lock 锁机制,是由index-row lock和gap lock组合成的
如,条件为col2>5,会在区间上[1,5],(5,正无穷)加index-row lock
08:30:02[test](;)> set tx_isolation='repeatable-read' ; 08:30:49[test](;)> select * from t1;+----+------+------+------+------+| id | col1 | col2 | col3 | col4 |+----+------+------+------+------+| 1 | 1 | 1 | 1 | 1 || 2 | 2 | 10 | 2 | 10 |+----+------+------+------+------+2 rows in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) 08:31:02[test](;)> begin; Query OK, 0 rows affected (0.00 sec) 08:31:05[test](;)> select * from t1 where col2>5 for update; +----+------+------+------+------+ | id | col1 | col2 | col3 | col4 | +----+------+------+------+------+ | 2 | 2 | 10 | 2 | 10 | +----+------+------+------+------+ 1 row in set (0.00 sec) 08:30:51[test](;)> begin; Query OK, 0 rows affected (0.00 sec) 08:32:11[test](;)> insert into t1 values(3,3,6,3,6); ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
---恢复内容结束---
mysql innodb目前使用范围最广的两种隔离级别为RC和RR,RR修复了RC中所存在的不可重复读
READ COMMITED
不可重复读
在同一事务中两次查看的结果集不同,如下session1的查看结果集受session2提交的事物影响
05:47:35[test](;)> select @@tx_isolation;+----------------+| @@tx_isolation |+----------------+| READ-COMMITTED |+----------------+ session1 03:28:11[test](;)> begin; Query OK, 0 rows affected (0.00 sec) 03:28:21[test](;)> select * from t1; Empty set (0.01 sec) session2 03:28:27[test](;)> insert into t1 values(1,1,1,1,1); Query OK, 1 row affected (0.00 sec) 03:29:25[test](;)> select * from t1; +----+------+------+------+------+ | id | col1 | col2 | col3 | col4 | +----+------+------+------+------+ | 1 | 1 | 1 | 1 | 1 | +----+------+------+------+------+ 1 row in set (0.00 sec)
幻影读(Phantom Rows)
什么是幻影读
同一事务保证了一致性读后,查询时对提交的事务是不可见的,但是变更的时候是可见的,所以就有可能引发幻影读
为什么会导致幻影读
对于update或delete操作(可以使用SELECT
with FOR UPDATE
or LOCK IN SHARE MODE
来进行模拟),innodb只加记录锁(满足条件索引记录)而不是gap锁,gap锁只用于外键约束和duplicate key的检查,所以允许另一事务在锁定的记录旁边自由插入新记录
如col2上有索引,在满足col2>5的条件索引上加索引(对于RC,只在col2为10的索引记录上加X lock),所以在另一会话总插入col2 为非10的记录则会成功
set tx_isolation='read-committed' ; session 1 07:46:16[test](;)> begin; Query OK, 0 rows affected (0.00 sec) 07:46:20[test](;)> select * from t1 where col2>5 for update; +----+------+------+------+------+ | id | col1 | col2 | col3 | col4 | +----+------+------+------+------+ | 2 | 2 | 10 | 2 | 2 | +----+------+------+------+------+ 1 row in set (0.00 sec) 07:44:48[test](;)> begin; Query OK, 0 rows affected (0.00 sec) 07:46:36[test](;)> insert into t1 values(3,3,6,3,3); Query OK, 1 row affected (0.00 sec) 07:46:38[test](;)> commit; Query OK, 0 rows affected (0.10 sec) 07:46:31[test](;)> select * from t1 where col2>5; +----+------+------+------+------+ | id | col1 | col2 | col3 | col4 | +----+------+------+------+------+ | 3 | 3 | 6 | 3 | 3 | | 2 | 2 | 10 | 2 | 2 | +----+------+------+------+------+ 2 rows in set (0.00 sec)
若col2上无索引,也会是同样的结果现象,如果条件字段上无索引,innodb会先将所有行都加上锁,然后返回给server层根据条件筛选,满足条件则释放行锁,不满足条件则不释放
REPEATABLE READ
如何实现可重复读
事物开始时记录当前的快照版本,事务期间读取的都是事务开始时的快照版本
如何避免幻影读
通过 next-key lock 锁机制,是由index-row lock和gap lock组合成的
如,条件为col2>5,会在区间上[1,5],(5,正无穷)加index-row lock
08:30:02[test](;)> set tx_isolation='repeatable-read' ; 08:30:49[test](;)> select * from t1;+----+------+------+------+------+| id | col1 | col2 | col3 | col4 |+----+------+------+------+------+| 1 | 1 | 1 | 1 | 1 || 2 | 2 | 10 | 2 | 10 |+----+------+------+------+------+2 rows in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) 08:31:02[test](;)> begin; Query OK, 0 rows affected (0.00 sec) 08:31:05[test](;)> select * from t1 where col2>5 for update; +----+------+------+------+------+ | id | col1 | col2 | col3 | col4 | +----+------+------+------+------+ | 2 | 2 | 10 | 2 | 10 | +----+------+------+------+------+ 1 row in set (0.00 sec) 08:30:51[test](;)> begin; Query OK, 0 rows affected (0.00 sec) 08:32:11[test](;)> insert into t1 values(3,3,6,3,6); ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
转载于:https://www.cnblogs.com/Bccd/p/7543903.html
RR隔离级别下通过next-key locks 避免幻影读相关推荐
- 【十四】MySQL Innodb RR隔离级别下到底是不是解决了幻读
我之前一直质疑网传mysql innodb的RR隔离级别下,next-key lock解决了幻读这种说法的准确性. 这次理顺了. 例子准备: 场景一.select * from user order ...
- InnoDB在RR隔离级别下解决幻读问题
表象:快照读(非阻塞读)-伪MVCC 内在:next-key锁(行锁+gap锁) 当前读和快照读 当前读:select-lock in share mode(共享锁),select-for updat ...
- mysql mvcc和行锁_mysql在RR的隔离级别下,究竟是通过MVCC解决幻读的还是通过行锁的next key算法解决的?...
首先,我们需要搞懂几个隔离级别的意思和每个隔离级别会出现的问题.隔离级别分为:读未提交,读提交,可重复读和可串行化. 读未提交是最低级别的隔离级别,表示当一个事务还没有提交时,他所做的变更就被别的事务 ...
- mysql trans begin_[原创]MySQL RR隔离级别下begin或start transaction开启事务后的可重复读?...
Server version: 5.6.21-log MySQL Community Server (GPL) 前提提要: 我们知道MySQL的RR(repeatable read)隔 ...
- Mysql RR隔离级别下,当前事务的更新前后ReadView查询结果不一致
先给个答案: 在可重复读(REPEATABLE READ)隔离级别下,当前事务是可以读取到当前事务修改的数据结果,这是通过 Read View 机制实现的. Read View 记录了事务开始时数据库 ...
- mysql rr解决幻读吗_mysql rr隔离级别解决幻读了吗
以下内容全部基于innodb. 虽然下面有很多概念很浅显,但还是要解释一下 什么是幻读? 当一个事务在多次查询中,发现了一行不是在当前事务中添加的数据.出现这种问题就叫做幻读. 关于四种隔离级别 未提 ...
- rc mysql common_RR与RC隔离级别下MySQL不同的加锁解锁方式
作者 韩杰·沃趣科技MySQL数据库工程师 出品 沃趣科技 | RC与RR隔离级别下MySQL不同的加锁解锁方式 MySQL5.7.21 数据准备 root@localhost : pxs ...
- MySQL RR隔离级别解决幻读问题?
首先,讲mysql的隔离级别之前需要复习一下事务的四个特性 (注:mysql存储引擎InnoDB)(待完善) 事务的四个特性(ACID): 原子性(Atomicity) 一致性(Consistency ...
- 深入学习InnoDB可重复读隔离级别下如何避免幻读
一.InnoDB可重复读隔离级别下如何避免幻读 在理解什么是幻读之前,先了解下脏读.幻读.不可重复读在实操场景中的现象. 脏读:指的就是一个事务读取到了另一个事务还未提交的数据,当该事物将数据回滚,则 ...
最新文章
- UVA 10269 Adventure of Super Mario
- 用英语说中国 IOS APP 上线
- python 文本分析库_Python有趣|中文文本情感分析
- Python生成Windows可执行exe文件
- React Native开发学习笔记——WebStorm运行项目
- IT与业务之间的鸿沟根源
- python三大特征六大原则_面向对象程序设计(Object Oriented Programming)的三大特性,六大原则...
- 电脑出货量_Q3季度全球笔记本电脑出货量增长34%,惠普出货量首次超过联想
- 毕马威_【毕马威快讯】毕马威发布个人信息保护法(草案)概览
- ReactNative 自定义封装Radio单选组件
- Easystructure教程_C语言源代码自动生成流程图
- matlab图像的直方图,Matlab图像直方图相关函数
- 什么是GRE词汇红宝书?
- 华为USG防火墙通过nat64 ipv6用户访问内网ipv4服务(原创,转发请注明出处)
- 2022年嵌入式系统设计师考试大纲
- 2019.11.13
- EasyPro_90B编程器烧录器使用操作方法
- C语言:调整数组顺序使其奇数位于偶数前面
- 修改文件与文件提交--乐字节Java
- unity 烘焙 光照贴图 以及一些灯光的相关问题(一)
热门文章
- java把信息存到文件里,Java 如何将字符串信息直接写保存到文本文件?
- python 匹配段落_Python3 如何使用正则表达式匹配段落开头?
- react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output and
- solidworks钣金插件_高效掌握SolidWorks钣金零件加工设计概念
- XamarinAndroid组件教程设置动画的设置插值器
- WEP自动破解工具wesside-ng
- 主板电源开关接口图解_电脑主板开机电路检修步骤及思路。
- zookeeper 分布式过程协同技术详解.pdf_阿里大牛耗时18个月整理这份ZooKeeper分布式详解文档...
- linux 网络传输压塑文件,萌新的Linux学习之路(十一)文件压缩传输
- Mac 设置文件默认打开方式