我在这里分享一篇关于 MySQL 的可重复读介绍,讲得挺好的,可以解决一些疑惑,链接在下方引用处。...但是,MySQL 的可重复读比 SQL 的可重复读的标准要更高,具体表现为:仅仅用 select 语句时幻读不会发生(这种情况简称 Phantom Reads),但是出现与写有关的操作时幻读会发生(这种情况简称...从定义上来看,Phantom Reads 和 Phantom Writes 都可以理解为幻读。 所以这就解释了某些文章会说 MySQL 的可重复读可以防止某些幻读情况的出现。...另外,从面试的角度来说,如果没有强调是 MySQL 的情况,可以忽略这些,只要按照 SQL 的关于幻读和可重复读的定义来回答即可。...引用: 一篇关于 MySQL 的可重复读介绍: https://blog.pythian.com/understanding-mysql-isolation-levels-repeatable-read
简单理解一下可重复读 可重复读是指:一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。 我们可以简单理解为:在可重复读隔离级别下,事务在启动的时候就”拍了个快照“。...这时,你可能就会想,如果一个库有 100G,那么我启动一个事务,MySQL就要拷贝 100G 的数据出来,这个过程得多慢啊。可是,我平时的事务执行起来很快啊。...在可重复读隔离级别下,一个事务在启动时,InnoDB 会为事务构造一个数组,用来保存这个事务启动瞬间,当前正在”活跃“的所有事务ID。”活跃“指的是,启动了但还没提交。...可重复读的核心是一致性读,而事务更新数据的时候,只能使用当前读,如果当前记录的行锁被其他事务占用,就需要进入锁等待。 参考 03 | 事务隔离:为什么你改了我还看不见?
事物隔离级别是可重复度: section 1: (1)创建数据库: create DATABASE TESTDB; (2)创建表: CREATE TABLE `t` (
为了更好的理解所以在MySQL数据库中测试复现这些问题。关于脏读和不可重复读在相应的隔离级别下都很容易的复现了。...但是对于幻读,我发现在可重复读的隔离级别下没有出现,当时想到难道是MySQL对幻读做了什么处理?...可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但是有时可能出现幻读数据。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。Mysql默认使用该隔离级别。...实现(隔离级别为可重复读) 在说到如何实现前先引入两个概念: 系统版本号:一个递增的数字,每开始一个新的事务,系统版本号就会自动递增。 事务版本号:事务开始时的系统版本号。...如何解决幻读 很明显可重复读的隔离级别没有办法彻底的解决幻读的问题,如果我们的项目中需要解决幻读的话也有两个办法: 使用串行化读的隔离级别 MVCC+next-key locks:next-key locks
MySQL中隔离级别分为4种,提未交读、读已提交、可重复读、串行化。同时MySQL默认隔离级别为可重复读。 ?...但是这种情况下的幻读在MySQL的可重复读情况下是不存在的,已经通过MVCC解决了。 我们可以通过以下方式来实现在可重复读情况产生的幻读。...答案是在事务B中查询的结果为3,而事务A中为1,或许很好理解事务A的值为什么是1,但是却并不好理解事务B为什么是3,这要从MySQL的MVCC开始说起 版本控制链 首先在Innodb中每一个事务都有一个事务...read view read view实际上就是一个数组,在可重复读隔离级别下,事务启动的时候就会产生一个read view直到事务结束。...读已提交和可重复读区别 在MySQL中可重复读和读已提交都是通过MVCC进行实现的,却别在于可重读是事务启动的时候就生成read view整个事务结束都一直使用这个read view,而在读已提交中则是每执行一条语句就重新生成最新的
什么是事务 事务的实现方式 不同机制下的不同隔离级别 幻读(P3/A3)和写偏斜(A5B) mysql中的可重复度 幻读 写偏斜 mysql中可重复读的实现 postgresql中的可重复读 无幻读 写偏斜...不同机制下的不同隔离级别 SQL标准定义了四种隔离级别,分别是读未提交,读已提交,可重复读,可串行化。...mysql中可重复读的实现 看源码可以发现,mysql中的读操作是使用MVCC机制实现,可以正确的查找到需要的行,但是写操作实现的时候有两点和我想的不太一样: 写操作永远读取已提交的数据,并没有走MVCC...根据这个实现,我们可以推理出,mysql的可重复读同样会发生lost update和read skew,只要测试的事务中存在写操作。...具体例子可见此处 mysql的可重复读是比SI更低的隔离级别,在发生幻读时,SI隔离级别事物的正确行为应该是后提交的事务回滚,而mysql两个事务都可以提交,显然,他的一致性更低,但是并发性更好(回滚率低
其他数据库 Oracle,SqlServer中都是选择读已提交(Read Commited)作为默认的隔离级别,为什么Mysql不选择读已提交(Read Commited)作为默认隔离级别,而选择可重复读...这里不想去搬binlog的概念了,就简单理解为binlog是一个记录数据库更改的文件吧。 binlog有几种格式?...而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!...解决方案 隔离级别设为可重复读(Repeatable Read),在该隔离级别下引入间隙锁。当Session 1执行delete语句时,会锁住间隙。...奈何这个格式在mysql5.1版本开始才引入。 因此由于历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题!
一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQLServer等,而MySQL却使用可重复读(Read-Repeatable,RR)。...隔离级别依次为>:串行化 > RR > RC >读未提交 在SQL标准中,前三种隔离级别分别解决了幻象读、不可重复读和脏读的问题。那么,为什么MySQL使用可重复读作为默认隔离级别呢?...而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!...如何解决? 解决方案有两种! (1)隔离级别设为可重复读(Repeatable Read),在该隔离级别下引入间隙锁。当Session 1执行delete语句时,会锁住间隙。...奈何这个格式在mysql5.1版本开始才引入。 因此由于历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题!
MySQL 百问百答 之 可重复读中的快照 MySQL 中的视图 view 查询语句定义的虚拟表,在调用的时候执行查询语句并生成语句。 InnoDB实现MVCC 用的一致性读视图。...快照在MVCC里是怎么工作的 2.1 什么是快照 在可重复读隔离级别下,事务在启动的时候就拍了快照,这个快照基于整个库。...2.2 快照如何实现 InnoDB中每个事务有一个唯一的事务ID,transaction id,在事务开始的时候申请,严格递增。...事务版本 事务ID 可重复读的定义是在事务启动和结束的这段期间,数据库的其他更新对当前事务不可见。...可重复读实现原理是,以当前事务启动时刻为准,有事务ID x,如果数据版本 大于x则表示实在事务启动后的新版本数据,则对当前事务不可见。
群里有小伙伴面试时,碰到面试官提了个很刁钻的问题:Mysql为何使用可重复读(Repeatable read)为默认隔离级别???...却使用可重复读(Read-Repeatable,RR)。...(Repeated Read):可重复读。...奈何这个格式在mysql5.1版本开始才引入。因此由于历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题!...一般是使用mysql自带分布式事务功能时才使用该隔离级别 RC和 RR 此时我们纠结的应该就只有一个问题了:隔离级别是用读已提交还是可重复读?
一.mysql事件隔离级别 1未提交读(READUNCOMMITTED) 另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据(脏读)( 隔离级别最低,并发性能高 ) 2....问题是,在同一个事务里,前后两次相同的SELECT会读到不同的结果(不重复读)。...会出现不可重复读、幻读问题(锁定正在读取的行) 3.可重复读(REPEATABLEREAD) 在同一个事务里,SELECT的结果是事务开始时时间点的状态,因此,同样的SELECT操作读到的结果会是一致的...会出幻读(锁定所读取的所有行) 4.串行化(SERIALIZABLE) 读操作会隐式获取共享锁,可以保证不同事务间的互斥(锁表) 二.脏读、不可重复读、幻读、复读 1.脏读 当前事务读到的数据是别的事务想要修改成为的但是没有修改成功的数据...2.不可重复读 当前事务先进行了一次数据读取,然后再次读取到的数据是别的事务修改成功的数据,导致两次读取到的数据不匹配,也就照应了不可重复读的语义 3.幻读 当前事务读第一次取到的数据比后来读取到数据条目少或者增加
为了解决当前读中的幻读问题,MySQL事务使用了Next-Key锁。 select * from table where ?...for update; insert; update ; delete; MVCC在MySQL的InnoDB中的实现如下: 在InnoDB中,会在每行数据后添加两个额外的隐藏的值来实现MVCC,这两个值一个记录这行数据何时被创建...在可重读Repeatable reads事务隔离级别下: 1.SELECT时,读取创建版本号当前事务版本号。
一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQLServer等,而MySQL却使用可重复读(Read-Repeatable,RR)。...隔离级别依次为>:串行化 > RR > RC >读未提交 在SQL标准中,前三种隔离级别分别解决了幻象读、不可重复读和脏读的问题。那么,为什么MySQL使用可重复读作为默认隔离级别呢?...而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!...如何解决? 解决方案有两种! (1)隔离级别设为可重复读(Repeatable Read),在该隔离级别下引入间隙锁。当Session 1执行delete语句时,会锁住间隙。...奈何这个格式在mysql5.1版本开始才引入。 因此由于历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题。
引入问题 这个问题来源于一个网络课程的课后思考题,题目是这样的: 我用下面的表结构和初始化语句作为试验环境,事务隔离级别是可重复读。...补充解释下这个问题,mysql环境,innodb引擎,事务的隔离级别是可重复读,一个表只有两个字段,然后插入4条数据,希望你构造上图中的一种情况,就是明明update了,但是结果没有更新,select也好像没有生效...给出问题的答案 先直接给出答案吧, 开启两个mysql的交互窗口,模拟两个事物的操作,比如一个事物叫A,一个事物叫B。...解释说明 要理解这个问题的答案,首先需要搞懂什么是可重复读的隔离级别。...可重复读隔离级别,事务 A 启动的时候会创建一个视图 read-view,之后事务 A 执行期间,即使有其他事务修改了数据,事务 A 看到的仍然跟在启动时看到的一样。
例如:脏读、不可重复读和幻读。而事务隔离级别就是用来解决这些问题的。MySQL中定义了四种事务隔离级别,不同的隔离级别会导致不同的并发执行结果。在实际应用中,需要根据业务的特点选择合适的隔离级别。...MySQL的四种事务隔离级别依次为:读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)...因此,针对不可重复读和幻读问题,需要使用更高的隔离级别。可重复读(Repeatable Read)在可重复读级别下,一个事务在执行期间多次读取同一行数据,将得到相同的结果。...因此,在该级别下解决了不可重复读问题。但是,仍然存在幻读问题。解决幻读问题需要引入行锁,MySQL中提供了next-key lock来实现。...总结MySQL提供了四种事务隔离级别,读未提交是最低的级别,因为它存在脏读问题。读已提交解决了脏读问题,但是仍然存在不可重复读和幻读问题。可重复读解决了不可重复读问题,但是仍然存在幻读问题。
下面我们先带着疑问,了解一下 MySQL 的相关原理 ,看完你就会明白这一切。...所以查找数据版本时候 MySQL 必须判断数据版本是否对当前事务可见。...4 这个规则可能比较绕,结合上面图片比较好理解。 以上判断规则可能比较抽象,看不懂,没事,我们再用大白话解释一下: 未提交事务生成的记录版本,不可见。...帮助文档 1: https://dev.mysql.com/doc/refman/8.0/en/innodb-multi-versioning.html 2 http://mysql.taobao.org.../monthly/2017/12/01/ 3 http://mysql.taobao.org/monthly/2018/11/04/ 4 https://dev.mysql.com/doc/refman
知识点总结 1.数据库默认隔离级别: mysql —可重复读; oracle,postgres —已提交读 2.mysql binlog的格式三种:statement,row,mixed 3.为什么mysql...默认是可重复读” 面试官:“为什么mysql选可重复读作为默认的隔离级别?” (你面露苦色,不知如何回答!) 面试官:"你们项目中选了哪个隔离级别?为什么?" 你:“当然是默认的可重复读,至于原因。。...Mysql默认的事务隔离级别是可重复读(Repeatable Read),那互联网项目中Mysql也是用默认隔离级别,不做修改么? 不是的,我们在项目中一般用读已提交这个隔离级别! what!...如何解决? 解决方案有两种! (1)隔离级别设为可重复读(Repeatable Read),在该隔离级别下引入间隙锁。当Session 1执行delete语句时,会锁住间隙。...奈何这个格式在mysql5.1版本开始才引入。因此由于历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题!
最近在面试的时候经常会问:如何理解重排和重绘? 我发现很多候选人都没有答道关键点上,感觉是在哪里看到过相关的文章,听起来零零散散,毫无逻辑。...错误示范 一般的面试过程就是这样的: 面试官:如何理解重排和重绘? 候选人:重排就是当页面的结构发生变化了,就会重排,比如改变变字体的大小,增删 DOM 元素这样的。...如果知道关键渲染路径的,基本引导一下还是可以搞明白,如果不清楚的,肯定是理解不了重排和重绘的。 考点 这道题我一般考察两个点: 浏览器的关键渲染路径。如果答不到这上面,一般这个题就凉了。...性能优化,如果减少重绘和回流,当然这个点肯定也是要基于对 关键渲染路径 的理解(这点不是关键点)。...优化关键渲染路径可提高渲染性能。 大致步骤是这样:在解析 HTML 时会创建 DOM,HTML 可以请求 JavaScript,而 JavaScript 反过来,又可以更改 DOM。
在 MySQL 中,最常见的去重方法有两个:使用 distinct 或使用 group by,那它们有什么区别呢?接下来我们一起来看。...我们先用 distinct 实现单列去重,根据 aid(文章 ID)去重,具体实现如下: 2.2 多列去重 除了单列去重之外,distinct 还支持多列(两列及以上)去重,我们根据 aid(文章...ID)和 uid(用户 ID)联合去重,具体实现如下: 2.3 聚合函数+去重 使用 distinct + 聚合函数去重,计算 aid 去重之后的总条数,具体实现如下: 3.group by...distinct 和 group by 的区别 官方文档在描述 distinct 时提到:在大多数情况下 distinct 是特殊的 group by,如下图所示: 官方文档地址:https://dev.mysql.com...by 和 distinct 都可以使用索引,此情况它们的性能是相同的;而当去重的字段没有索引时,distinct 的性能就会高于 group by,因为在 MySQL 8.0 之前,group by
领取专属 10元无门槛券
手把手带您无忧上云