简单来说就是通过mvcc + next-key locks 防止幻读

幻读是什么?

当前事务读取了一个范围的记录,另一个事务在该范围内插入了新记录,当前事务再次读取该范围内的记录就会发现新插入的记录,这就是幻读

以下MySQL的隔离界别都是可重复读(RR)

mvcc与next-key分别在什么情况下起作用?

  1. 在快照读的情况下,会通过mvcc来避免幻读
  2. 在当前读的情况下,会通过next-key来避免幻读

快照读与当前读

  1. 快照读:所有普通的select语句都算快照读,它并不会给表中任何记录做加锁操作,其他事务可以对表中记录做任何改动

  2. 当前读:加锁的操作都叫当前读,分为s锁,x锁

    • 共享锁:S锁。在事务要读取一条记录时,需要先获取该记录的S锁

      select … lock in share mode

    • 独享锁(排他锁):X锁。事务要改动一条记录时,需要先获取X锁

      select … for update、insert、update、delete

      S锁与S锁是兼容的;S锁与X锁是不兼容;X锁与X锁也是不兼容。

简单了解下跟防止幻读有关的行级锁

  1. record locks:把当前记录上锁

  2. gap locks:如果当前列具有唯一索引,那么就仅仅是把当前行加锁;只有当前列没有索引或者具有非唯一索引,才会锁定前面的间隙

什么意思呢?

如下例:

CREATE TABLE `user` (`id` int NOT NULL,`score` int DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB;
insert into user values(1,79),(3,91),(6,59);

事务1 事务2
1 begin;
select * from user where score=91 for update;
2 begin;
insert into user values(2,98); // 因为gap锁的原因,插入失败
commit;
3 commit;

也就是在 id (1, 3) 之间加x锁

而如果把事务1的查询语句改成

select * from user where id=3 for update;

则前面的间隙不会上锁,事务2会成功插入!

  1. next-key locks:就是record locks跟gap locks的组合,既能保护该条记录,又能防止其他事务插入该记录前面的间隙中。

    如上述加x锁的区间就变成了 (1, 3]

简单了解下mvcc

  1. 具有三个隐藏字段:

    • DB_TRX_ID:记录最后进行插入、更新操作的事务

    • DB_ROLL_PTR:滚动指针,指向修改前的记录

    • DB_ROW_ID:如果没有聚簇索引,该字段会构建聚簇索引(相当于隐藏的自增主键)

  2. readview:会记录当前活跃事务的id范围,根据事务id来判断哪个版本是对当前事务可见的

    如下例(还是上面表,默认三条数据):

事务1 事务2
1 begin;
update user set score=50 where id=1;
update user set score=60 where id=1;
2 begin;
select * from user where id=1; //score=79
3 commit;
4 select * from user where id=1; //score=79
commit;

​ 为什么?

​ 假设事务1的事务id是100

  1. **事务1未提交:**事务2在执行select之前会生成一个readview,活跃的只有事务1,该readview的事务范围就是100,在该范围内都不符合要求。根据滚动指针(DB_ROLL_PTR)找之前的版本,直到事务id小于100,也就是找到事务1开启之前的版本,那时的score就是79
DB_TRX_ID(事务id) id score DB_ROLL_PTR(滚动指针)
1 100 1 60 2
2 100 1 50 3
3 80(肯定小于100) 1 79
  1. 事务1提交:

    • 上述的例子是在MySQL默认隔离级别(RR)下,在该隔离级别下,只在第一次select前生成一个readview。在事务1未提交之前已经生成过了,所以搜索到的score还是79。
    • 如果隔离级别是RC,那么第二次select前会再次生成一个readview,那么score就是60

上面内容过一遍后,在回过头来考虑幻读问题,这不就已经解决了嘛!

  • 快照读的情况下,通过mvcc来避免幻读
  • 当前读的情况下,通过next-key来避免幻读

MySQL解决幻读详解相关推荐

  1. MySQL幻读详解及解决方法

    1. 什么是幻读? 建立一张表如下: 按照下面步骤执行两个事务. 事务1: 事务2: 由此,可以把幻读理解为:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已 ...

  2. mysql 脏读 不可重复读 幻读_mysql事务隔离级别/脏读/不可重复读/幻读详解

    一.四种事务隔离级别 1.1read uncommitted 读未提交 即:事务A可以读取到事务B已修改但未提交的数据. 除非是文章阅读量,每次+1这种无关痛痒的场景,一般业务系统没有人会使用该事务隔 ...

  3. 不可重复读和幻读详解(必看!!!)

    前言:看了很多关于MySQL隔离级别的视频和文章,发现了一个问题,大家都是说,不可重复读是在一个事务中读到了另一个事务提交后修改后的数据,而幻读是一个事务读到了另一个事务中添加并提交后的数据.那么删除 ...

  4. MySQL锁与脏读、不可重复读、幻读详解

    一.MySQL锁 1.锁简介 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的 计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据 ...

  5. MySQL之幻读的详解、实例及解决办法

    事务隔离级别(tx_isolation) mysql 有四级事务隔离级别 每个级别都有字符或数字编号 读未提交 READ-UNCOMMITTED | 0:存在脏读,不可重复读,幻读的问题 读已提交 R ...

  6. 【MySQL系列5】深入分析MySQL中锁并详解锁解决幻读问题

    MySQL锁分析 MySQL系列文章汇总 前言 什么是锁 锁的分类 全局锁 表锁 行锁 共享锁 排他锁 意向锁 各种锁的兼容关系 锁到底锁的是什么 举例猜测 结论 行锁的算法 记录锁(Record L ...

  7. MySQL中的InnoDB是怎么解决幻读的?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | Aaron_涛 来源 | blog.csdn. ...

  8. mysql 快照读 幻读,InnoDB的MVCC如何解决不可重复读和快照读的幻读,当前读用next-key解决幻读...

    InnoDB默认的隔离级别是RR(可重复读),可以解决脏读和不可重复读,只解决了快照读情况下的幻读问题,当前读情况下解决幻读问题得靠next-key锁. mysql如何实现避免幻读: 在快照读读情况下 ...

  9. MySQL 到底是怎么解决幻读的?

    作者:LastSun https://www.cnblogs.com/wdy1184/p/10655180.html 一.什么是幻读 在一次事务里面,多次查询之后,结果集的个数不一致的情况叫做幻读.而 ...

最新文章

  1. mysql 分区指定路径_[数据库]MySQL 指定各分区路径
  2. bootstrap table教程--使用入门基本用法
  3. docker 无法正常启动或版本信息会报错 Cannot connect to the Docker daemon at
  4. SAP Fiori问题排查:Why expand does not work for complex note
  5. 7z压缩文档的powershell示例
  6. php 数组的定义方法,PHP中数组定义的几种方法
  7. ubuntu 16.04 编译android,Ubuntu 16.04 64bit 编译 Android 4.4 源码
  8. linux命令别名永久生效
  9. Android之Camera拍照
  10. python删库命令_python3 删除数据库
  11. android instance区别,Android singleTask 和singleInstance的区别
  12. 软件中的快速原型技术
  13. UINO优锘:数字孪生助力运维工程场景化可视化管理
  14. LIO-SAM后端中的回环检测及位姿计算
  15. thinkphp内核家教平台网站源码带手机站
  16. java后台如何将rgb与16进制颜色进行转换
  17. 大数据中心显示大屏幕用液晶拼接屏还是led显示屏?
  18. hibernate 二级缓存 @cache注解
  19. 手机端怎么限制wifi网速
  20. 《网安学习之道》预告

热门文章

  1. python文件处理——encoding参数,utf-8,gbk
  2. ubuntu18.04企业微信字体
  3. Trinity安装全过程并解决部分报错
  4. ansys 定义变量(关联模型)
  5. 英语人机考试计算机算分吗,过来人跟你说说英语人机对话考试的经验
  6. 计算机安全知识策划书,安全知识竞赛策划书模板
  7. 02前端入门HTML5 +CSS3+电商网页制作:CSS
  8. CSS、HTML补充
  9. PLC为什么急停按钮是常闭不是常开呢?
  10. 深度学习笔记(三十一)三维卷积及卷积神经网络