MySQL 是如何解决幻读的
MySQL 是如何解决幻读的
一、什么是幻读
在一次事务里面,多次查询之后,结果集的个数不一致的情况叫做幻读。
而多出来或者少的哪一行被叫做 幻行
二、为什么要解决幻读
在高并发数据库系统中,需要保证事务与事务之间的隔离性,还有事务本身的一致性。
三、MySQL 是如何解决幻读的
如果你看到了这篇文章,那么我会默认你了解了 脏读 、不可重复读与可重复读。
1. 多版本并发控制(MVCC)(快照读/一致性读)
多数数据库都实现了多版本并发控制,并且都是靠保存数据快照来实现的。
以 InnoDB 为例,每一行中都冗余了两个字断。一个是行的创建版本,一个是行的删除(过期)版本。
具体的版本号(trx_id)存在 information_schema.INNODB_TRX 表中。
版本号(trx_id)随着每次事务的开启自增。
事务每次取数据的时候都会取创建版本小于当前事务版本的数据,以及过期版本大于当前版本的数据。
普通的 select 就是快照读。
select * from T where number = 1;
原理:将历史数据存一份快照,所以其他事务增加与删除数据,对于当前事务来说是不可见的。
2. next-key 锁 (当前读)
next-key 锁包含两部分
- 记录锁(行锁)
- 间隙锁
记录锁是加在索引上的锁,间隙锁是加在索引之间的。(思考:如果列上没有索引会发生什么?)
select * from T where number = 1 for update;
select * from T where number = 1 lock in share mode;
insert
update
delete
原理:将当前数据行与上一条数据和下一条数据之间的间隙锁定,保证此范围内读取的数据是一致的。
其他:MySQL InnoDB 引擎 RR 隔离级别是否解决了幻读
引用一个 github 上面的评论 地址:
Mysql官方给出的幻读解释是:只要在一个事务中,第二次select多出了row就算幻读。
a事务先select,b事务insert确实会加一个gap锁,但是如果b事务commit,这个gap锁就会释放(释放后a事务可以随意dml操作),a事务再select出来的结果在MVCC下还和第一次select一样,接着a事务不加条件地update,这个update会作用在所有行上(包括b事务新加的),a事务再次select就会出现b事务中的新行,并且这个新行已经被update修改了,实测在RR级别下确实如此。如果这样理解的话,Mysql的RR级别确实防不住幻读
有道友回复 地址:
在快照读读情况下,mysql通过mvcc来避免幻读。
在当前读读情况下,mysql通过next-key来避免幻读。
select * from t where a=1;属于快照读
select * from t where a=1 lock in share mode;属于当前读不能把快照读和当前读得到的结果不一样这种情况认为是幻读,这是两种不同的使用。所以我认为mysql的rr级别是解决了幻读的。
先说结论,MySQL 存储引擎 InnoDB 隔离级别 RR 解决了幻读问题。
如引用一问题所说,T1 select 之后 update,会将 T2 中 insert 的数据一起更新,那么认为多出来一行,所以防不住幻读。看着说法无懈可击,但是其实是错误的,InnoDB 中设置了 快照读 和 当前读 两种模式,如果只有快照读,那么自然没有幻读问题,但是如果将语句提升到当前读,那么 T1 在 select 的时候需要用如下语法: select * from t for update (lock in share mode) 进入当前读,那么自然没有 T2 可以插入数据这一回事儿了。
注意
- next-key 固然很好的解决了幻读问题,但是还是遵循一般的定律,隔离级别越高,并发越低。
MySQL 是如何解决幻读的的更多相关文章
- 何为幻读?MySQL又是如何解决幻读的?
一.什么是幻读 在一次事务里面,多次查询之后,查询的结果集的个数不一致的情况叫做幻读.而多出来或者少的哪一行被叫做 幻行 二.为什么要解决幻读 在高并发数据库系统中,需要保证事务与事务之间的隔离性,还 ...
- 【大厂面试03期】MySQL是怎么解决幻读问题的?
问题分析 首先幻读是什么? 根据MySQL文档上面的定义 The so-called phantom problem occurs within a transaction when the same ...
- MySQL是怎么解决幻读问题的?
前言 我们知道MySQL在可重复读隔离级别下别的事物提交的内容,是看不到的.而可提交隔离级别下是可以看到别的事务提交的.而如果我们的业务场景是在事物内同样的两个查询我们需要看到的数据都是一致的,不能被 ...
- MySQL到底能否解决幻读问题
先说结论,MySQL 存储引擎 InnoDB 在可重复读(RR)隔离级别下是解决了幻读问题的. 方法:是通过next-key lock在当前读事务开启时,1.给涉及到的行加写锁(行锁)防止写操作:2. ...
- MySQL 到底是怎么解决幻读的?
; 原理:将历史数据存一份快照,所以其他事务增加与删除数据,对于当前事务来说是不可见的. 2. next-key 锁 (当前读) next-key 锁包含两部分: 记录锁(行锁) 间隙锁 记录锁是加在 ...
- MySQL的可重复读级别能解决幻读吗
引言 之前在深入了解数据库理论的时候,了解到事物的不同隔离级别可能存在的问题.为了更好的理解所以在MySQL数据库中测试复现这些问题.关于脏读和不可重复读在相应的隔离级别下都很容易的复现了.但是对于幻 ...
- MYSQL如何解决幻读
第一部分 首先要了解下mysql数据库的事务特征之一隔离级别: READ UNCOMMITTED(未提交读): 在READUNCOMMITTED级别,事务中的修改,即使没有提交,对其他事务也都是可见的 ...
- MySQL锁(三)行锁:幻读是什么?如何解决幻读?
概述 前面两篇文章介绍了MySQL的全局锁和表级锁,今天就介绍一下MySQL的行锁. MySQL的行锁是各个引擎内部实现的,不是所有的引擎支持行锁,例如MyISAM就不支持行锁. 不支持行锁就意味着在 ...
- MySQL的可重复读级别能解决幻读问题吗?
之前在深入了解数据库理论的时候,了解到事务的不同隔离级别可能存在的问题.为了更好的理解所以在MySQL数据库中测试复现这些问题.关于脏读和不可重复读在相应的隔离级别下都很容易的复现了. 但是对于幻读, ...
随机推荐
- gitbook 入门教程之环境要求
gitbook 是基于 node.js 的命令行工具,首先需要安装并配置好 node.js 环境,然后才能安装gitbook 相关工具. 由于安装工具全部都是国外网站,因此速度可能会很慢,也可能需要F ...
- mssql sqlserver isnull coalesce函数用法区别说明
摘要: 下文讲述isnull及coalesce空值替换函数的区别 isnull.coalesce函数区别:1.isnull 只能接受两个参数,而coalesce函数可以接受大于等于两个以上参数2.is ...
- python3 生成器初识 NLP第五条
话不多说,先把第五条抄一遍: 五,沟通的意义在于对方的回应 沟通没有对与错,只有“有效果”或者“没有效果”之分. 自己说得多“对”没有意义,对方收到你想表达的讯息才是沟通的意义. 因此自己说什么不重要 ...
- 在WebStorm里配置watcher实现编辑less文件时自动生成.map和压缩后的.css文件
[文件(File)]-[设置(Settings)]-[工具(Tools)]-[File Watchers]-[+]-[Less]打开New Watcher配置界面. https://blog.csdn ...
- PHP全栈学习笔记5
php与mysql数据库,PHP支持很多数据库,与mysql为牛逼组合,mysql数据库的基础知识的掌握是由必要的,要了解如何操作mysql数据库,数据表的方法. 什么是数据库,数据库能做什么,数据库 ...
- 剑指Spring源码(二)
这是春节后的第一篇博客,我在构思这篇博客的时候,一度想放弃,想想要不要换个东西写,因为毕竟个人水平有限,Spring源码实在博大精深,不是我这个菜的抠脚的菜鸡可以驾驭的,怕误人子弟,还有就是源码分析类 ...
- docker初体验,搭建自用的gitlab服务
一.前言 git在如日中天的版本管理系统,现在如果不是工作在git版本管理系统下,几乎都不好意思给人打招呼.现在就有现成的互联网的git服务器提供给大家使用,例如号称程序的社交网络github. 正好 ...
- Mybatis之旅第四篇-输入输出映射
一.引言 在日常开发用到mybatis时,因为实际的开发业务场景很复杂,不论是输入的查询条件,还是返回的结果,经常是需要根据业务来定制,这个时候我们就需要自己来定义一些输入和输出映射 二.parame ...
- AlertConfirmDialog【基于AlertDialog的确认取消对话框】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 确认取消对话框,基于AlertDialog.不是基于DialogFragment. 按钮文本可以根据实际情况更换. 效果图 代码分析 ...
- springboot~openfeign从JSON文件读取数据
对openfeign不清楚的同学可以先看我这篇文章:springboot~openfeign从此和httpClient说再见 对于openfeign来说,帮助我们解决了服务端调用服务端的问题,你不需要 ...