在MySQL中,使用MVCC来实现REPEATABLE-READ隔离级别,由于SELECT操作不会对数据加锁,其他回话可以修改当前回话所读取过的数据而不会被阻塞,因此读写不冲突。

在MVCC并发控制中,读操作可以分成两类:快照读 (snapshot read)与当前读 (current read)。快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁。当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。(抄自MySQL 加锁处理分析

当事务中进行查询时,MySQL会把快照读和当前读的结果进行合并再返回给客户端,而这个合并可能导致一些奇特的结果。

生成测试数据:

drop table tb002;
create table tb002(id int primary key,c2 int,unique index uni_c2(c2));
begin;
insert into tb002(id,c2) select 1,1;
insert into tb002(id,c2) select 2,2;
insert into tb002(id,c2) select 4,4;
commit;

假设有回话A和回话B,均使用REPEATABLE-READ隔离级别

##========================================================##

首先回话A执行SQL:

begin;
select * from tb002;

返回结果如下:

##========================================================##

然后回话B执行SQL:

begin;
delete from tb002 where id=2;
commit;

由于回话A没有加锁,所以回话B能顺利完成删除并提交事务,当前数据库中无C2=2的记录,且会话B提交事务释放锁。

##========================================================##

回到回话A执行SQL:

insert into tb002(id,c2) select 3,2;

由于当前数据库中无C2=2的记录,且其他回话没有在此C2=2的范围上加锁,因此回话A可以完成C2=2的数据插入。

在回话A上再次进行查询:

select * from tb002;

返回结果如:

C2上有唯一索引,但为什么查询结果中仍包含两条C2=2的记录呢?ID=2的记录属于快照读的数据,ID=3的记录数据当前读的数据,MySQL将当前读和快照读的数据进行简单的合并后返回给客户端,并不检查“结果数据是否满足唯一索引”的要求。

##========================================================##

上面的测试针对唯一索引进行,那如果针对主键会有啥区别呢?

将插入SQL修改为:

insert into tb002(id,c2) select 2,3;

即回话B删除的ID值和回话A新插入的ID值相同情况下,最后的查询结果并不会包含两条相同ID的记录,对于“快照读”和“当前读”两个结果集存在"主键冲突“的情况,最终返回客户端的结果会”丢弃“快照读中的”老版本“记录,保留最新版本的记录。

可见对于主键不存在上述问题。

##========================================================##

总结:

在基于MVCC实现的REPEATABLE-READ隔离级别下,由于快照读和当前读的影响,会导致返回数据结果集超过”期望结果集“的情况,甚至返回结果集中包含重复的”唯一索引键“,但返回结果集中不会包含重复的“主键”(PS:单表查询的前提下)。

如果在事务中包含先插入后查询的情况,应该考虑上述问题对业务的影响。

##========================================================##

MySQL--REPEATABLE-READ隔离级别下读取到的“重复数据”的更多相关文章

  1. Mysql 间隙锁原理,以及Repeatable Read隔离级别下可以防止幻读原理(百度)

    Mysql知识实在太丰富了,前几天百度的面试官问我MySql在Repeatable Read下面是否会有幻读出现,我说按照事务的特性当然会有, 但是面试官却说 Mysql 在Repeatable Re ...

  2. MySQL Transaction--RR事务隔离级别下加锁测试

    ============================================================================== 按照非索引列更新 在可重复读的事务隔离级别 ...

  3. MySQL Transaction--RC事务隔离级别下加锁测试

    ==============================================================================非索引列更新 在读提交的事务隔离级别下,在非 ...

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

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

  5. 【MySQL】MySQL锁和隔离级别浅析一

    <MySQL技术内幕InnoDB存储引擎>第一版中对于MySQL的InnoDB引擎锁进行了部分说明,第二版有部分内容更新. 与MySQL自身MyISAM.MSSQL及其他平台BD锁的对比: ...

  6. 浅析MySQL InnoDB的隔离级别

    MySQL InnoDB存储引擎中事务的隔离级别有哪些?对应隔离级别的实现机制是什么? 本文就将对上面这两个问题进行解答,分析事务的隔离级别以及相关锁机制. 隔离性简介 隔离性主要是指数据库系统提供一 ...

  7. mysql事务之一:MySQL数据库事务隔离级别(Transaction Isolation Level)及锁的实现原理

    一.数据库隔离级别 数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 1 #可选参数 ...

  8. 一文读懂MySQL的事务隔离级别及MVCC机制

    回顾前文: 一文学会MySQL的explain工具 一文读懂MySQL的索引结构及查询优化 (同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论不一定适用于其他版本) 就软件开 ...

  9. 【mysql】- 事务隔离级别和MVCC篇

    概念 术语 脏写( Dirty Write ): 如果一个事务修改了另一个未提交事务修改过的数据,那就意味着发了脏写 脏读( Dirty Read ) : 如果一个事务读到了另一个未提交事务修改过的数 ...

随机推荐

  1. Cain工具ARP欺骗攻击

    OS:Win7工具:Cainhttp://pan.baidu.com/s/1xq9lW 密码:409z 网络:本机和被攻击电脑有线连接路由器. Cain是有名的局域网嗅探工具,有丰富的功能.比如可以解 ...

  2. bzoj:1299: [LLH邀请赛]巧克力棒

    原题:http://www.lydsy.com/JudgeOnline/problem.php?id=1299 众多dalao的题解已经很详细了:http://blog.csdn.net/wzq_qw ...

  3. [bzoj1969] [Ahoi2005]LANE 航线规划

    tarjan.并查集.树状数组.树链剖分. 时间倒流,变删边为加边. 先求一波边双联通分量,缩点. 题目保证最后还是整张图联通的..所以就是一棵树. 现在的操作就是,将路径上的边权置0(加边时),查询 ...

  4. And Then There Was One(约瑟夫问题变形)

    题目链接:http://poj.org/problem?id=3517 And Then There Was One Time Limit: 5000MS   Memory Limit: 65536K ...

  5. SpringMVC框架学习笔记——各种异常、报错解决

    1.Target runtime com.genuitec.runtime.generic.jee60 is not defined. 找到导入项目的.setting文件夹org.eclipse.ws ...

  6. zookeeper基本讲解及基本命令和配置 (转)

    一.ZooKeeper概述 ZooKeeper是一种为分布式应用所设计的高可用.高性能且一致的开源协调服务,是Google的Chubby一个开源实现,是Hadoop和Hbase的重要组件,它提供了一项 ...

  7. ehcachexml文件解释

    怎么修改默认配置

  8. 蓝桥杯 0/1背包问题 (java)

      今天第一次接触了0/1背包问题,总结一下,方便以后修改.不对的地方还请大家不啬赐教! 上一个蓝桥杯的例题: 数据规模和约定 代码: import java.util.Scanner; public ...

  9. 安卓Acitivity的启动模式

    活动的四大启动模式 Ps:除了standar模式外,其他启动模式都要在AndroidManifest.xml中设置 android:lauchMode的值 安卓活动的启动模式(LaunchMode)有 ...

  10. thinkphp使用PHPMailer发送邮件

    第一步:准备PHPMailer 使用PHPMailer发送邮件,首先下载个PHPMailer 将下载的PHPMailer放到ThinkPHP文件夹里面的ThinkPHPExtendVendor 第二步 ...