MySQL中幻读是如何解决的
在我们的数据库隔离级别中幻读的解决是在串行化的级别下进行处理的,虽然这种方法可以解决幻读,但是这种方法在高并发下效率是非常低的,经过学习了解到两种解决幻读的方法:加间隙锁和MVCC。
加间隙锁
间隙锁:将数据分为不同区间,对该区间进行加锁。作用在索引上,其目的是为了防止同一事物的两次当前读出现幻读的情况。如果对一条记录添加了间隙锁,并不会影响其他事务对这条记录加记录锁或者继续加gap锁。
比如说我们有1,3,5,10,12这几条数据:
在当前事务对5-9中的数据进行一次查询并添加间隙锁后,另一个事务想要在5-9这个范围中添加数据是会阻塞的或者说添加失败。也就是说使用间隙锁后,其他事务就不能在加锁的范围中添加数据,这样就可以防止幻读的产生
1、session A 先对9进行查询并在(5-10)范围添加间隙锁,
2、session B 也对9进行查询并在(5 - 10)范围添加间隙锁
3、此时session B想插入9这条记录,由于session A对(5 - 10)进行了加锁,所以不会插入成功
4、同时seesion A也想插入9这条记录,由于session B对(5 - 10)也进行了加锁,插入操作不会成功,此时B在等待A会话完成,A在等待B会话完成,所以出现了死锁现象
MVCC
MVCC也就是多版本并发控制,不需要通过加锁手段就能读到正确版本的数据,其存在目的是在保证数据一致性的前提下提供一种高并发的访问性能。
换言之,就是为了查询一些正在被另一个事务更新的行,并且获取到更新前的值,这样在做查询时就不用等待另一个事务释放锁。
MVCC实现原理:隐藏字段,undo log,ReadView
隐藏字段:在InnoDB存储引擎中,对于每一条记录都会有隐藏字段,包括ROWID,事务ID(最新一次被哪个事务修改),回滚指针
ReadView: 当前数据的快照
- 在
READ COMMITTED
隔离级别下,一个事务执行过程中每次执行SELECT操作都会生成一个ReadView,ReadView本身就保证了事务不可以读取到未提交的事务做出的修改,也就避免了脏读现象 - 在
REPETABLE READ
隔离级别下,一个事务执行过程中只有第一次执行SELECT操作时才会生成一个ReadView,之后的SELECT操作都是复用这个ReadView,这也就避免了不可重复度和幻读
ReadView规则
ReadView到底是怎么避免幻读的,这就需要知道ReadView都包括什么:
ReadView中包括有:生成ReadView的当前事务,生成ReadVIew时活跃(尚未提交)的事务列表(事务ID从小到大进行排列),以及列表中的最小事务ID(up_limit_id),以及下一个尚未分配过的事务ID(low_limit_id)
详细规则:
如果所查询的数据的隐藏字段中的事务ID就是当前ReadView中的事务ID,则表示当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问到
如果所查询的数据的隐藏字段中的事务ID小于当前ReadView中的
up_limit_id
,则表示所查询数据是被修改并已经提交的,所以该版本可以被当前事务访问到如果所查询的数据的隐藏字段中的事务ID大于当前ReadView中的
low_limit_id
,则表示所查询的数据是在当前事务之后被修改过的,所以不能被当前事务访问到如果所查询的数据的隐藏字段中的事务ID在
up_limit_id
和low_limit_id
范围之内:- 如果所查询的数据的隐藏字段中的事务ID和范围中的某个事务ID相同,则表示修改了数据的事务还是活跃的,没有提交,所以不能被当前事务访问
- 如果所查询的数据的隐藏字段中的事务ID和范围中的某个事务ID没有相同的,则表示事务已经提交,所以可以被当前事务访问到
MVCC执行流程
- 开启事务时会有一个事务ID(单纯的查询事务ID为0)
- 获取ReadView
- 查询得到的数据与ReadView中事务版本号进行比较
- 如果不符合ReadView规则,则要从
undo log
中获取历史快照 - 最后返回符合规则的数据
MySQL中幻读是如何解决的相关推荐
- mysql中幻读出现的原因及解决方案
今天分享 mysql中幻读出现的原因及解决方案: 一.首先明确什么是幻读: 事务A按照一定条件进行数据读取,期间事务B插入了相同搜索条件的新数据,事务A再次按照原先条件进行读取操作修改时,发现了事 ...
- MySQL中幻读现象
幻读:即由可重复读隔离级别引发的事务问题,有些人说幻读就是一次事务中读取到的数据条数不一样,我不太认可这句话,当然这句话并没有什么问题,但是由初学者来理解的话很容易进误区! 幻读场景1: 场景2:银行 ...
- MySQL中的InnoDB是怎么解决幻读的?
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | Aaron_涛 来源 | blog.csdn. ...
- MySQL面试三连杀:如何实现可重复读、又为什么会出现幻读、是否解决了幻读问题?...
作者 | sanyuesan0000 来源 | https://blog.csdn.net/sanyuesan0000 事务隔离级别有四种,mysql默认使用的是可重复读,mysql是怎么实现可重复读 ...
- mysql 幻读 mvcc_MVCC 能解决幻读吗?
MySQL通过MVCC(解决读写并发问题)和间隙锁(解决写写并发问题)来解决幻读 MySQL InnoDB事务的隔离级别有四级,默认是"可重复读"(REPEATABLE READ) ...
- 美团三面:一直追问我, MySQL 幻读被彻底解决了吗?
之前有位小伙伴美团三面,一直被追求「幻读是否被 MySQL 可重复度隔离级别彻底解决了?」 之前我也提到过,MySQL InnoDB 引擎的默认隔离级别虽然是「可重复读」,但是它很大程度上避免幻读现象 ...
- MySQL之幻读的详解、实例及解决办法
事务隔离级别(tx_isolation) mysql 有四级事务隔离级别 每个级别都有字符或数字编号 读未提交 READ-UNCOMMITTED | 0:存在脏读,不可重复读,幻读的问题 读已提交 R ...
- mysql可重复读_到底什么是mysql的幻读和不可重复读
幻读和不可重复读的定义 事务A 按照一定条件进行数据读取, 期间事务B 插入了相同搜索条件的新数据,事务A再次按照原先条件进行读取时,发现了事务B 新插入的数据称为幻读. 如果事务A 按一定条件搜索, ...
- 什么是脏读?不可重复读?幻读?如何解决?
什么是脏读?不可重复读?幻读?如何解决? 朋友最近面试美团,被面试官问到数据库的幻读问题,自己正好最近复习到这,做个笔记整理一下数据库的三大特征以及隔离级别. 一.先来回顾一下什么是事务,以及事务的四 ...
- 【MySQL系列5】深入分析MySQL中锁并详解锁解决幻读问题
MySQL锁分析 MySQL系列文章汇总 前言 什么是锁 锁的分类 全局锁 表锁 行锁 共享锁 排他锁 意向锁 各种锁的兼容关系 锁到底锁的是什么 举例猜测 结论 行锁的算法 记录锁(Record L ...
最新文章
- Python 出现 can't use a string pattern on a bytes-like object
- c#大文件读取和写入数据库
- BZOJ 4802: 欧拉函数(大数因数分解算法 Pollard_rho 和素数测试算法 Miller_Rabin)
- Android逆向:二进制xml文件解析 之 Start Tag Chunk
- leetcode310. 最小高度树(bfs)
- CSS之左定宽度右自适应宽度并且等高布局
- python爬取知乎问题_python爬取知乎首页问题
- 排序算法笔记(Java)
- Spring3 整合 Hibernate4实现数据库操作(1)
- Android UI 优化——使用HierarchyViewer工具
- 在ubuntu里烧win10安装盘
- 图灵奖背后:一个奥斯卡拿到手软,一个公司卖了 160 亿
- 读取SqlServer表名及结构
- c mysql中文乱码解决方案_Linux下c读取MysqL中文乱码解决方案
- linux7防火墙端口映射,服务器使用firewall进行端口映射端口转发
- Linux 下查看局域网内所有主机IP和MAC
- kali安装navicat
- 贝叶斯算法-情感分类
- 福岛第1核电站2号3号反应堆辐射量急剧上升
- 【JAVA内存回收】Java 内存回收机制
热门文章
- 概率论基础 - 5 - 马尔可夫不等式
- html如何制作斜线表头表格,2种方法教你怎样在WPS excel中绘制表格斜线表头
- NLP--解决Mac OS 10.14.4Python下pip install pyhanlp 失败
- Hive实现同比环比计算
- C语言学习阶段性总结!(内附超详知识导图+重点知识详解)
- win10 linux efi分区大小,EFI模式 win10+Ubuntu16.04双系统
- iphone 竖屏的视频转换为横屏
- java wps linux 安装_安装wps for linux无法启动
- R语言数据异常值处理
- 基于51单片机的知识