不可重复读和幻读 重
如有侵权请联系本人删除
首先了解acid与mysql
MySQL事务之ACID实现原理(全方位解读)
深入学习MySQL事务:ACID特性的实现原理
二者很相似,不可重复读指的是对同一条记录(可以理解为对同一行)前后两次的读取结果是不一样的。
幻读指的是一个事务读取两次,得到的记录条数不一致。
幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读可能发生在update操作中,而幻读发生在insert,delete操作中。
mysql解决不可重复读的方法:
mysql中,默认的事务隔离级别是可重复读(repeatable-read),为了解决不可重复读,innodb采用了mvcc(多版本并发控制)来解决这一问题。(mvcc顺便也解决了一部分幻读:快照读)
mvcc是利用在每条数据后面加了隐藏的两列(创建版本号和删除版本号),每个事务在开始的时候都会有一个递增的版本号
rr rc中的s,x锁
读已提交(Read Committed):解决了脏读问题。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。这可以通过“瞬间共享读锁”和“排他写锁”实现, 即事物需要对某些数据进行修改必须对这些数据加 X 锁,读数据时需要加上 S 锁,当数据读取完成后立刻释放 S 锁,不用等到事物结束。
可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但是有时可能出现幻读数据。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。Mysql默认使用该隔离级别。这可以通过“共享读锁”和“排他写锁”实现,即事物需要对某些数据进行修改必须对这些数据加 X 锁,读数据时需要加上 S 锁,当数据读取完成并不立刻释放 S 锁,而是等到事物结束后再释放。
两种锁的sql语句(当前读) MySQL 共享锁 (lock in share mode),排他锁 (for update)
其实在MySQL可重复读的隔离级别中并不是完全解决了幻读的问题,而是解决了读数据情况下的幻读问题。而对于修改的操作依旧存在幻读问题,就是说MVCC对于幻读的解决时不彻底的。例子:
图源:https://blog.csdn.net/QAQ123666/article/details/105084758
图源:https://www.php.cn/mysql-tutorials-460111.html
在MySQL中,通过多版本并发控制(MVCC)去避免幻读的问题,但是只是在select的时候可以避免幻读,update之后再select还是可能会出现幻读现象。
Innodb 引擎为了解决「可重复读」隔离级别使用「当前读」而造成的幻读问题,就引出了 next-key 锁,就是记录锁和间隙锁的组合。
普通的查询是快照读,是不会看到别的事务插入的数据的。可重复读隔离级是由
MVCC(多版本并发控制)实现的,实现的方式是启动事务后,在执行第一个查询语句后,会创建一个视图,然后后续的查询语句都用这个视图,「快照读」读的就是这个视图的数据,视图你可以理解为版本数据,这样就使得每次查询的数据都是一样的。MySQL
里除了普通查询是快照度,其他都是当前读,比如update、insert、delete,这些语句执行前都会查询最新版本的数据,然后再做进一步的操作。这很好理解,假设你要 update 一个记录,另一个事务已经 delete 这条记录并且 提交事务了,这样不是会产生冲突吗,所以
update 的时候肯定要知道最新的数据。另外,select … for update 这种查询语句是当前读,每次执行的时候都是读取最新的数据。
因此,要讨论「可重复读」隔离级别的幻读现象,是要建立在「当前读」的情况下。
所以,Innodb 引擎为了解决「可重复读」隔离级别使用「当前读」而造成的幻读问题,就引出了 next-key 锁,就是记录锁和间隙锁的组合。
记录锁,锁的是记录本身; 间隙锁,锁的就是两个值之间的空隙,以防止其他事务在这个空隙间插入新的数据,从而避免幻读现象。
需要注意的是,next-key lock 锁的是索引,而不是数据本身,所以如果 update 语句的 where 条件没有用到索引列,那么就会全表扫描,在一行行扫描的过程中,不仅给行加上了行锁,还给行两边的空隙也加上了间隙锁,相当于锁住整个表,然后直到事务结束才会释放锁。
所以在线上千万不要执行没有带索引的 update 语句,不然会造成业务停滞,然后被老板教育了一波
不可重复读和幻读 重相关推荐
- SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因...
原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...
- 什么是脏读,不可重复读,幻读
1. 脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据. 2. 不可重复读 :是指在一个事务内,多次 ...
- 脏读,不可重复读,幻读
MySQL事务隔离级别: 在介绍脏读,不可重复读,幻读现象之前,我们先来了解MySQL的事务隔离级别,因为脏读,不可重复读,幻读等现象都是由数据库里的事务隔离级别来决定是否可能发生的. 在MySQL里 ...
- mysql 乐观锁 脏读_mysql 丢失更新1和2、脏读、不可重复读和幻读 事务隔离级别 悲观锁 乐观锁...
事务是现代关系型数据库的核心之一.在多个事务并发操作数据库(多线程.网络并发等)的时候,如果没有有效的避免机制,就会出现以下几种问题: ( 第一类丢失更新 A事务撤销时,把已经提交的B事务的更新数据覆 ...
- 通俗地解释脏读、不可重复读、幻读
spring(数据库)事务隔离级别分为四种(级别递减): 1.Serializable (串行化):最严格的级别,事务串行执行,资源消耗最大: 2.REPEATABLE READ(重复读) :保证了一 ...
- 仅此一文让你明白事务隔离级别、脏读、不可重复读、幻读
网络上关于这方面的博文有些偏理论,有些通篇代码,都不能深入浅出.本文用图文并茂的方式,配上行云流水般的代码,非要摆清楚这个问题.相关代码已提交至码云(点击这里下载). 事务是现代关系型数据库的核心之一 ...
- sql怎么读_大白话讲解脏写、脏读、不可重复读和幻读
一般对于我们的业务系统去访问数据库而言,它往往是多个线程并发执行多个事务的,对于数据库而言,它会有多个事务同时执行,可能这多个事务还会同时更新和查询同一条数据,所以这里会有一些问题需要数据库来解决 我 ...
- !何为脏读、不可重复读、幻读
2.0.前言 事务的隔离性是指多个事务并发执行的时候相互之间不受到彼此的干扰的特性,隔离性是事务ACID特性中的I,根据隔离程度从低到高分为Read Uncommitted(读未提交),Read Co ...
- 事务相关、不可重复读与幻读的区别
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 事务内嵌套事务: 1) 都用spring事务时,取决spring采用的事务的隔离级别. ...
最新文章
- php正则表达式2,php正则表达式(2)
- 用yui compressor 压缩 javascirpt脚本
- [云炬创业基础笔记] 第四章测试14
- [省选联考 2020 A/B 卷] 信号传递(状压dp + 卡空间)
- @FeignClient中的@RequestMapping也被SpringMVC加载的问题解决
- plsql developer 创建表空间和临时表
- linux建立动态库链接,Linux动态链接库.so文件的创建与使用
- Python suds error “'NoneType' object has no attribute 'promotePrefixes'”
- HttpClient 如何正确的释放资源
- Flutter 生命周期
- Python 库的使用 —— dis
- Mobile First! Wijmo 5 之 架构
- 最新黑马java十次方社交项目教程
- 3D打印机将用于太空食物 未来或可打印披萨
- Gym - 101350E Competitive Seagulls——博弈
- 计算机导论 宋斌,宋斌(计算机科学与技术学院)老师 - 南京理工大学 - 院校大全...
- 还在付费使用 XShell?我选择这款超牛逼的 SSH 客户端,完全免费!
- 适合团队工作的软件,大家来看看有没有喜欢的吧
- 管廊复杂网格参数化算法及其大数据在线渲染
- 数据库—应用系统开发方法