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
RR隔离级别下通过next-key locks 避免幻影读的更多相关文章
- InnoDB MVCC RR隔离级别下的数据可见性总结
一.背景 熟悉数据库隔离级别的人都知道,在RR(可重复读)隔离级别下,无论何时多次执行相同的SELECT快照读语句,得到的结果集都是完全一样的,即便两次SELECT语句执行期间,其他事务已经改变了该查 ...
- [原创]MySQL RR隔离级别下begin或start transaction开启事务后的可重复读?
Server version: 5.6.21-log MySQL Community Server (GPL) 前提提要: 我们知道MySQL的RR(repeatable read)隔 ...
- MySQL Transaction--RR事务隔离级别下加锁测试
============================================================================== 按照非索引列更新 在可重复读的事务隔离级别 ...
- Mysql 间隙锁原理,以及Repeatable Read隔离级别下可以防止幻读原理(百度)
Mysql知识实在太丰富了,前几天百度的面试官问我MySql在Repeatable Read下面是否会有幻读出现,我说按照事务的特性当然会有, 但是面试官却说 Mysql 在Repeatable Re ...
- MySQL Transaction--RC事务隔离级别下加锁测试
==============================================================================非索引列更新 在读提交的事务隔离级别下,在非 ...
- Innodb 中 RR 隔离级别能否防止幻读?
问题引出 我之前的一篇博客 数据库并发不一致分析 有提到过事务隔离级别以及相应加锁方式.能够解决的并发问题. 标准情况下,在 RR(Repeatable Read) 隔离级别下能解决不可重复读(当行修 ...
- InnoDB在MySQL默认隔离级别下解决幻读
1.结论 在RR的隔离级别下,Innodb使用MVVC和next-key locks解决幻读,MVVC解决的是普通读(快照读)的幻读,next-key locks解决的是当前读情况下的幻读. 2.幻读 ...
- 浅析SQL Server在可序列化隔离级别下,防止幻读的范围锁的锁定问题
本文出处:http://www.cnblogs.com/wy123/p/7501261.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
- MySQL--REPEATABLE-READ隔离级别下读取到的“重复数据”
在MySQL中,使用MVCC来实现REPEATABLE-READ隔离级别,由于SELECT操作不会对数据加锁,其他回话可以修改当前回话所读取过的数据而不会被阻塞,因此读写不冲突. 在MVCC并发控制中 ...
随机推荐
- Java编程基础-面向对象(中)
本章承接Java编程基础-面向对象(上)一文. 一.static关键字 在java中,定义了一个static关键字,它用于修饰类的成员,如成员变量.成员方法以及代码块等,被static修饰的成员具备一 ...
- springclould feign客户端添加全局参数
用springclould feign作为调用服务的客户端,一般来说参数可以写在feignclient的方法参数里 有时需要所有feign请求都统一添加一些参数,例如token用于鉴权等,可以这样做: ...
- Android程序初体验
第一个程序的实现的最终功能是: 点击"正确"或者"错误"会得到一个是否正确的提示. 直接上效果图. 此次涉及代码编写的文件有4个: package co ...
- codevs 1267 老鼠的旅行 2012年CCC加拿大高中生信息学奥赛
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description You are a mouse that lives in a cage in ...
- ubuntu 14.04 安装mysql,并配置远程连接和中文乱码
1. 安装MySQL的jar root@computer-PowerEdge-T30:~# sudo apt-get install mysql-server mysql-client在本次安装中,根 ...
- dataSource' defined in class path resource [org/springframework/boot/autocon
spring boot启动的时候抛出如下异常: dataSource' defined in class path resource [org/springframework/boot/autocon ...
- 成魔笔记1——先入IT,再成魔
关于我为什么要写这个博客的原因,做一个简单的解释.因为报考的一时兴起,我选择了软件专业.可是三年下来,感觉自己没做多少事,也没收获到多少东西.很多时候都是老师讲什么,都是完全陌生的东西,跟不上教学的思 ...
- VM虚拟机下的Linux不能上网
虚拟机linux上网配置 图解教程 首先查看window7主机下的网络配置VMNet1或VMNet8是否开启,其实linux系统的网络连接跟linux系统一致 在虚拟机界面将桥接改为NAT连接 点虚拟 ...
- Luogu P3727 曼哈顿计划E 点分治+hash
题目: P3727曼哈顿计划E 分析: 大长题面容易给人一种不可做的错觉,但是这题考的知识点都是我们熟悉的. 稍加分析我们可以得到,我们可以把每个点当成一个单独的游戏,如果k=1,就是简单的nim游戏 ...
- tkinter学习-文本框
阅读目录 Entry 输入框 Text 文本框 Entry: 说明:输入控件,用于显示简单的文本内容 属性:在输入框中用代码添加和删除内容,同样也是用insert()和delete()方法 from ...