MySQL--REPEATABLE-READ隔离级别下读取到的“重复数据”
在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隔离级别下读取到的“重复数据”的更多相关文章
- Mysql 间隙锁原理,以及Repeatable Read隔离级别下可以防止幻读原理(百度)
Mysql知识实在太丰富了,前几天百度的面试官问我MySql在Repeatable Read下面是否会有幻读出现,我说按照事务的特性当然会有, 但是面试官却说 Mysql 在Repeatable Re ...
- MySQL Transaction--RR事务隔离级别下加锁测试
============================================================================== 按照非索引列更新 在可重复读的事务隔离级别 ...
- MySQL Transaction--RC事务隔离级别下加锁测试
==============================================================================非索引列更新 在读提交的事务隔离级别下,在非 ...
- [原创]MySQL RR隔离级别下begin或start transaction开启事务后的可重复读?
Server version: 5.6.21-log MySQL Community Server (GPL) 前提提要: 我们知道MySQL的RR(repeatable read)隔 ...
- 【MySQL】MySQL锁和隔离级别浅析一
<MySQL技术内幕InnoDB存储引擎>第一版中对于MySQL的InnoDB引擎锁进行了部分说明,第二版有部分内容更新. 与MySQL自身MyISAM.MSSQL及其他平台BD锁的对比: ...
- 浅析MySQL InnoDB的隔离级别
MySQL InnoDB存储引擎中事务的隔离级别有哪些?对应隔离级别的实现机制是什么? 本文就将对上面这两个问题进行解答,分析事务的隔离级别以及相关锁机制. 隔离性简介 隔离性主要是指数据库系统提供一 ...
- mysql事务之一:MySQL数据库事务隔离级别(Transaction Isolation Level)及锁的实现原理
一.数据库隔离级别 数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 1 #可选参数 ...
- 一文读懂MySQL的事务隔离级别及MVCC机制
回顾前文: 一文学会MySQL的explain工具 一文读懂MySQL的索引结构及查询优化 (同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论不一定适用于其他版本) 就软件开 ...
- 【mysql】- 事务隔离级别和MVCC篇
概念 术语 脏写( Dirty Write ): 如果一个事务修改了另一个未提交事务修改过的数据,那就意味着发了脏写 脏读( Dirty Read ) : 如果一个事务读到了另一个未提交事务修改过的数 ...
随机推荐
- [译]Python作为一种编程语言有多强大?
Quora上有个问题:Python作为一种编程语言有多强大? 以下是Patrycja Okowicka的回答 说实话,Python是一门强大的语言,几乎所有东西都可以用Python创建!这就是为什么它 ...
- python 数据类型之集合
一.集合的定义: 定义:由不同元素组成的集合,集合中是一组无序排列的可hash值,可以作为字典的key. 特性:集合的目的是将不同的值存放到一起,不同的集合间用来做关系运算,无需纠结于集合中单个值 二 ...
- 阻止a标签的默认事件及延伸
先贴一段代码 <html lang="en"> <head> <meta charset="UTF-8"> <meta ...
- Java入门篇(二)——Java语言基础(上)
本篇我们开始进入Java的学习,首先在学习如何编写Java语言前要先了解Java程序的基本结构. 一.Java程序的基本结构 一个Java程序的基本结构大体可以分为包.类.main()主方法.标识符. ...
- [译]Dapper教程
脑子里突然浮现出一个想法:尝试翻译一些技术文档.说干就干,先来翻译个最近经常查阅的Dapper教程,有兴趣的园友可以一起参与进来 dapper-tutorial-cn. 什么是Dapper Dappe ...
- bzoj:1687;poj 2434:[Usaco2005 Open]Navigating the City 城市交通
Description A dip in the milk market has forced the cows to move to the city. The only employment av ...
- [51nod1443]路径和树
给定一幅无向带权连通图G = (V, E) (这里V是点集,E是边集).从点u开始的最短路径树是这样一幅图G1 = (V, E1),其中E1是E的子集,并且在G1中,u到所有其它点的最短路径与他在G中 ...
- NowCoderWannafly挑战赛3-B.遇见
遇见 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 65536K,其他语言131072K64bit IO Format: %lld 题目描述 A和B在同一条路上,他们之间的距离为 k ...
- [国嵌笔记][029][ARM处理器启动流程分析v2]
2440启动流程 启动方式:nor flash启动.nand flash启动 地址布局: 选择nor flash启动时,SROM(nor flash)地址为0x00000000 选择nand flas ...
- Docker+Jenkins持续集成环境(3)集成PMD、FindBugs、Checkstyle静态代码检查工具并邮件发送检查结果
为了规范代码,我们一般会集成静态代码检测工具,比如PMD.FindBugs.Checkstyle,那么Jenkins如何集成这些检查工具,并把检查结果放到构建邮件里呢? 今天做了调研和实现,过程如下 ...