1、数据脏读
事务a修改了某条数据,然后事务b读取了事务a修改的该条数据,然后事务a由于某些原因,事务a回滚了,这样事务b读到的数据就和回滚的数据不同了,这时事务b读取的数据就是脏数据。概况一句话就是一个事务读取了另一个事务未提交的数据。

2、数据幻读
事务a按一定条件读取了该表的一些数据,然后事务b想该表插入了一些满足事务a查询条件的数据,当事务a再次以相同条件查询数据时,会发现多出来一些数据,就好像产生了幻觉一样,我们称为幻读

3、不可重复读
事务a读取了某条数据,事务a没有提交,然后事务b修改了该条数据,这时事务a再次读取该条数据,这样两次读取的数据不同,我们成为该条数据为不可重复读。概况一句话就是一个事务多次读取某条数据,发现读取的数据不完全相同。

一、什么是幻读
在一次事务里面,多次查询之后,结果集的个数不一致的情况叫做幻读。
而多或者少的那一行被叫做 幻行
二、为什么要解决幻读
在高并发数据库系统中,需要保证事务与事务之间的隔离性,还有事务本身的一致性。
三、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 InnoDB支持三种行锁定方式:
  行锁(Record Lock):锁直接加在索引记录上面,锁住的是key。
  间隙锁(Gap Lock):锁定索引记录间隙,确保索引记录的间隙不变。间隙锁是针对事务隔离级别为可重复读或以上级别而已的。
  Next-Key Lock :行锁和间隙锁组合起来就叫Next-Key Lock。
  锁选择
如果更新条件没有走索引,例如执行”update from t1 set v2=0 where v2=5;” ,此时会进行全表扫描,扫表的时候,要阻止其他任何的更新操作,所以上升为表锁。
如果更新条件为索引字段,但是并非唯一索引(包括主键索引),例如执行“update from t1 set v2=0 where v1=9;” 那么此时更新会使用Next-Key Lock。使用Next-Key Lock的原因:
首先要保证在符合条件的记录上加上排他锁,会锁定当前非唯一索引和对应的主键索引的值;
还要保证锁定的区间不能插入新的数据。
如果更新条件为唯一索引,则使用Record Lock(记录锁)。
InnoDB根据唯一索引,找到相应记录,将主键索引值和唯一索引值加上记录锁。但不使用Gap Lock(间隙锁)

mysql脏读,幻读,不可重复读以及间隙所解决幻读相关推荐

  1. MySQL可重复读隔离级别能解决幻读吗?

    事务及事务隔离级别 innodb存储引擎支持事务,myisam不支持事务 事务内的操作要么全部成功,要么全部失败,中途有失败则回滚 事务的ACID:原子性,一致性,隔离性,持久性 事务隔离级别需要解决 ...

  2. 909-MySQL的MVCC机制下,可重复读级别不能完全解决虚读

    MySQL使用MVCC(Multi-Version Concurrency Control,多版本并发控制)机制,默认隔离级别是RR(可重复读).MySQL使用mvcc的RR级别,并不能解决幻读的问题 ...

  3. mysql不可重复读和重复读_MySql隔离级别:RU / RC / RR / S + 脏读 / 不可重复读 / 幻读 / 可重复读...

    MySQL 事务 本文所说的 MySQL 事务都是指在 InnoDB 引擎下,MyISAM 引擎是不支持事务的. 数据库事务指的是一组数据操作,事务内的操作要么就是全部成功,要么就是全部失败,什么都不 ...

  4. mysql可重复读和间隙锁_解决MySQL可重复读——详解间隙锁

    间隙锁(Gap Lock)是Innodb在可重复读提交下为了解决幻读问题时引入的锁机制,(下面的所有案例没有特意强调都使用可重复读隔离级别)幻读的问题存在是因为新增或者更新操作,这时如果进行范围查询的 ...

  5. mysql 中的脏读与幻读_一文带你理解脏读,幻读,不可重复读与mysql的锁,事务隔离机制...

    首先说一下数据库事务的四大特性 1 ACID 事务的四大特性是ACID(不是"酸"....) (1) A:原子性(Atomicity) 原子性指的是事务要么完全执行,要么完全不执行 ...

  6. mysql 可重复读 悲观锁_一文带你理解脏读,幻读,不可重复读与mysql的锁,事务隔离机制...

    首先说一下数据库事务的四大特性 1 ACID 事务的四大特性是ACID(不是"酸"....) (1) A:原子性(Atomicity) 原子性指的是事务要么完全执行,要么完全不执行 ...

  7. mysql数据库的事务 acid 隔离级别 脏读 脏写 幻读 不可重复读

    事务的四大特征 原子性(atomicity):要么全部提交(commit),要么全部回滚(rollback) 一致性(consistency):数据从一个合法状态转换成另一种合法状态 隔离性(isol ...

  8. MySQL --- 19♪ 进阶15 TCL事务控制语言--建立结束事务/设置断点--默认隔离级别--脏读/幻读/不可重复读

    #TCL事物控制语言 : /*   Transaction control language : 事物控制语言   事务:     一个或者一组sql语句组成一个执行单元,这个执行单元要么全部执行,要 ...

  9. mysql悲观锁会有脏数据吗_一文带你理解脏读,幻读,不可重复读与mysql的锁,事务隔离机制...

    首先说一下数据库事务的四大特性 1 ACID 事务的四大特性是ACID(不是"酸"....) (1) A:原子性(Atomicity) 原子性指的是事务要么完全执行,要么完全不执行 ...

最新文章

  1. CSS的优先级和继承性
  2. 计算机乘除法运算中部分积和余数的符号位选择与位移的关系
  3. 对标 VS Code,JetBrains 的下一代 IDE :Fleet
  4. 一个好用的Chrome倒数计时器扩展 - Calendar and Countdown
  5. 三条中线分的六个三角形_八年级数学上册:三角形已知两条边如何求第三边
  6. SLAM GMapping(5)运动模型
  7. Android解压/重新打包system.img
  8. ArcGIS图层和要素的过滤显示
  9. 阿里云OSS前端直传踩坑
  10. ubuntu下各种软件下载
  11. bluehost 盗版_如何免费使用bluehost设置电子邮件地址并连接到gmail或Outlook 2020
  12. 六度分离(Six Degrees of Separation)理论
  13. 重装系统服务器2012r2,SCCM2012R2网络部署重装系统
  14. Graham算法解决凸包问题
  15. 前端ajax实现分页思路详解
  16. 企业证书打包ipa文件(图文详解)
  17. 【转】P2P-BT对端管理协议
  18. 距离-视觉-惯性里程计:无激励的尺度可观测性(ICRA2021)
  19. 五子棋-完美解决闪屏问题版-新增悔棋功能(C++实现)
  20. 网页引用优酷视频并添加封面自动播放

热门文章

  1. C++/QT生成二维码和扫瞄二维码
  2. 基于OpenWRT+FreeRadius+TinyRadius+Daloradius实现portal加radius安全认证
  3. xdebug3的配置文件不生效,提示waiting for incoming connection with ide key ‘xxx‘
  4. jquery.flot 在节点上显示提示
  5. Windows系统时间同步出错解决办法(w32tm /register按回车,可能是为了解决时间COM注册的问题)
  6. C语言中指针是什么?
  7. php.ini 关闭输出缓冲,php 输出缓冲 Output Control用法实例详解
  8. Ubuntu/Windows双系统安装巨详细——全面解决各种问题(疑难杂症),有手就行
  9. 同等学力计算机 百度云,2020计算机二级题库百度云_圣考研网
  10. 带动画效果的下拉菜单