首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

mysql 什么是可重复读

MySQL中的可重复读(Repeatable Read)​是一种事务隔离级别,其核心目标是确保事务在执行过程中多次读取同一数据时结果一致,同时避免脏读(读取未提交的数据)。以下是其关键特点和实现原理:

1. ​定义与核心特性

  • 一致性读:事务启动时创建数据快照,整个事务期间读取的数据基于该快照,不受其他事务提交的影响。
  • 防止脏读:无法读取其他事务未提交的修改数据。
  • 行级锁:修改数据时锁定该行,防止其他事务同时修改或删除。

2. ​实现原理

  • 多版本并发控制(MVCC)​:每行记录保存创建和删除的系统版本号。事务读取时仅查看版本号≤自身事务版本的数据,确保读取到的是事务开始时的数据。
  • 快照隔离:事务内部所有SELECT操作均基于启动时的数据快照,即使其他事务提交新数据或修改,当前事务仍读取旧版本数据。

3. ​优势与局限性

  • 优势
    • 事务内多次读取同一数据结果一致,适合金融、库存管理等需强一致性的场景。
    • 通过MVCC和行锁平衡了并发性能与数据一致性。
  • 局限性
    • 幻读问题:可能读取到其他事务插入的新数据(如范围查询结果不一致)。例如,事务A多次查询某范围数据时,事务B插入新记录并提交,事务A后续查询可能看到新数据。
    • 解决方式
      • 提升隔离级别至串行化(Serializable)​,但会降低并发性能。
      • 使用范围锁(如SELECT ... FOR UPDATE)或乐观锁(版本号控制)。

4. ​应用场景

  • 金融系统:确保交易数据的准确性和一致性。
  • 库存管理:防止超卖或库存状态不一致。

示例代码

代码语言:javascript
复制
sql-- 设置事务隔离级别为可重复读
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT * FROM your_table WHERE id = 1;  -- 读取事务启动时的数据快照
-- 其他操作...
COMMIT;

总结来说,可重复读通过MVCC和快照机制实现了事务内数据的一致性,但需注意其无法完全解决幻读问题,需结合具体场景选择优化策略

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

MySQL是如何实现可重复读的?

简单理解一下可重复读 可重复读是指:一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。 我们可以简单理解为:在可重复读隔离级别下,事务在启动的时候就”拍了个快照“。...注意,这个快照是基于整个库的。 这时,你可能就会想,如果一个库有 100G,那么我启动一个事务,MySQL就要拷贝 100G 的数据出来,这个过程得多慢啊。可是,我平时的事务执行起来很快啊。...在可重复读隔离级别下,一个事务在启动时,InnoDB 会为事务构造一个数组,用来保存这个事务启动瞬间,当前正在”活跃“的所有事务ID。”活跃“指的是,启动了但还没提交。...我们假设事务B在更新的看不到事务C的修改,是什么个情况?...可重复读的核心是一致性读,而事务更新数据的时候,只能使用当前读,如果当前记录的行锁被其他事务占用,就需要进入锁等待。 参考 03 | 事务隔离:为什么你改了我还看不见?

2.2K11

MySQL 的可重复读

我在这里分享一篇关于 MySQL 的可重复读介绍,讲得挺好的,可以解决一些疑惑,链接在下方引用处。...但是,MySQL 的可重复读比 SQL 的可重复读的标准要更高,具体表现为:仅仅用 select 语句时幻读不会发生(这种情况简称 Phantom Reads),但是出现与写有关的操作时幻读会发生(这种情况简称...所以这就解释了某些文章会说 MySQL 的可重复读可以防止某些幻读情况的出现。...另外,从面试的角度来说,如果没有强调是 MySQL 的情况,可以忽略这些,只要按照 SQL 的关于幻读和可重复读的定义来回答即可。...引用: 一篇关于 MySQL 的可重复读介绍: https://blog.pythian.com/understanding-mysql-isolation-levels-repeatable-read

1.8K21
  • MySQL数据库的默认隔离级别为什么是可重复读

    一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQLServer等,而MySQL却使用可重复读(Read-Repeatable,RR)。...隔离级别依次为>:串行化 > RR > RC >读未提交 在SQL标准中,前三种隔离级别分别解决了幻象读、不可重复读和脏读的问题。那么,为什么MySQL使用可重复读作为默认隔离级别呢?...这个是有历史原因的,要从主从复制开始讲起了! 1.主从复制,是基于什么复制的? 是基于binlog复制的 2.binlog有几种格式?...而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!...因此由于历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题。

    2.1K10

    从一个问题来解释下什么是mysql的可重复读

    引入问题 这个问题来源于一个网络课程的课后思考题,题目是这样的: 我用下面的表结构和初始化语句作为试验环境,事务隔离级别是可重复读。...补充解释下这个问题,mysql环境,innodb引擎,事务的隔离级别是可重复读,一个表只有两个字段,然后插入4条数据,希望你构造上图中的一种情况,就是明明update了,但是结果没有更新,select也好像没有生效...解释说明 要理解这个问题的答案,首先需要搞懂什么是可重复读的隔离级别。...可重复读隔离级别,事务 A 启动的时候会创建一个视图 read-view,之后事务 A 执行期间,即使有其他事务修改了数据,事务 A 看到的仍然跟在启动时看到的一样。...接着,事物 A 执行select语句,为什么结果还是以前的数据呢?是因为事物 A 的select使用的一致读,也叫快照读,读取的还是以前的快照数据。

    87530

    为什么 MySQL 选择 可重复读 作为默认隔离级别?

    其他数据库 Oracle,SqlServer中都是选择读已提交(Read Commited)作为默认的隔离级别,为什么Mysql不选择读已提交(Read Commited)作为默认隔离级别,而选择可重复读...原因 这个是有历史原因的,当然要从我们的主从复制开始讲起了! 主从复制,是基于什么复制的?   是基于binlog复制的!...而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!...解决方案 隔离级别设为可重复读(Repeatable Read),在该隔离级别下引入间隙锁。当Session 1执行delete语句时,会锁住间隙。...因此由于历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题!

    1.2K21

    Mysql RCRR隔离原理和区别 不可重复读和可重复读

    Mysql RC/RR隔离原理和区别 不可重复读和可重复读 mysql四种隔离级别: 1.未提交读(READ UNCOMMITED)脏读 2.已提交读 (READ COMMITED)简称(RC) 不可重复读...3.可重复读(REPEATABLE READ)简称(RR) 4.可串行化(SERIALIZABLE) 这个不用验证了,所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰了,一般不用,性能特别低...总结∶ 可重复读级别下(RR),开启事务之后第一个select才会生成快照,而不是事务一开始就生成快照。...Oracle 默认使用READ COMMITTED(读已提交)隔离级别 MySQL默认使用REPEATABLE(可重复读)隔离级别 以下是测试步骤: 1.mysql客户端SQLyog测试无效,需要通过...确保每个事务对数据库的读写操作是相互独立的。 概念: 并发事务会出现更新丢失、脏读、不可重复读,幻读。 更新丢失:当两个或多个事务更新同一行记录,会产生更新丢失现象。

    27610

    MySQL可重复读和读已提交实现原理,MVCC是如何实现的。

    MySQL中隔离级别分为4种,提未交读、读已提交、可重复读、串行化。同时MySQL默认隔离级别为可重复读。 ?...但是这种情况下的幻读在MySQL的可重复读情况下是不存在的,已经通过MVCC解决了。 我们可以通过以下方式来实现在可重复读情况产生的幻读。...3.MVCC版本控制 、 如果表中数据如如下所示,同时隔离级别为可重复读那么按照下面的时间进行执行,此时你觉得事务A和事务B查询的结果会是什么呢?...答案是在事务B中查询的结果为3,而事务A中为1,或许很好理解事务A的值为什么是1,但是却并不好理解事务B为什么是3,这要从MySQL的MVCC开始说起 版本控制链 首先在Innodb中每一个事务都有一个事务...读已提交和可重复读区别 在MySQL中可重复读和读已提交都是通过MVCC进行实现的,却别在于可重读是事务启动的时候就生成read view整个事务结束都一直使用这个read view,而在读已提交中则是每执行一条语句就重新生成最新的

    8.1K62

    MySQL的可重复读级别能解决幻读吗

    但是对于幻读,我发现在可重复读的隔离级别下没有出现,当时想到难道是MySQL对幻读做了什么处理?...可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但是有时可能出现幻读数据。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。Mysql默认使用该隔离级别。...MVCC 多版本并发控制(Multi-Version Concurrency Control, MVCC)是MySQL中基于乐观锁理论实现隔离级别的方式,用于实现读已提交和可重复读取隔离级别的实现。...快照读和当前读 出现了上面的情况我们需要知道为什么会出现这种情况。在查阅了一些资料后发现在RR级别中,通过MVCC机制,虽然让数据变得可重复读,但我们读到的数据可能是历史数据,不是数据库最新的数据。...,这就实现了可重复读了。

    2.5K21

    MySQL 乱七八糟的可重复读隔离级别实现

    什么是事务 事务的实现方式 不同机制下的不同隔离级别 幻读(P3/A3)和写偏斜(A5B) mysql中的可重复度 幻读 写偏斜 mysql中可重复读的实现 postgresql中的可重复读 无幻读 写偏斜...什么是事务 事务是数据库一组读写操作的集合,事务具有ACID四个特性,原子性,一致性,隔离性和持久性。 事务有四个隔离级别,分别是读未提交,读已提交,可重复读和串行化。...mysql中可重复读的实现 看源码可以发现,mysql中的读操作是使用MVCC机制实现,可以正确的查找到需要的行,但是写操作实现的时候有两点和我想的不太一样: 写操作永远读取已提交的数据,并没有走MVCC...具体例子可见此处 mysql的可重复读是比SI更低的隔离级别,在发生幻读时,SI隔离级别事物的正确行为应该是后提交的事务回滚,而mysql两个事务都可以提交,显然,他的一致性更低,但是并发性更好(回滚率低...postgresql中的可重复读 无幻读 pg实现的隔离级别是比较标准的,可重复度级别(实际是SI)没有幻读,这里举两个例子 第一个例子 ?

    1.2K30

    MySQL的可重复读级别能解决幻读吗

    但是对于幻读,我发现在可重复读的隔离级别下没有出现,当时想到难道是MySQL对幻读做了什么处理?...可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但是有时可能出现幻读数据。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。Mysql默认使用该隔离级别。...MVCC 多版本并发控制(Multi-Version Concurrency Control, MVCC)是MySQL中基于乐观锁理论实现隔离级别的方式,用于实现读已提交和可重复读取隔离级别的实现。...快照读和当前读 出现了上面的情况我们需要知道为什么会出现这种情况。在查阅了一些资料后发现在RR级别中,通过MVCC机制,虽然让数据变得可重复读,但我们读到的数据可能是历史数据,不是数据库最新的数据。...,这就实现了可重复读了。

    71410

    什么是重定位?为什么需要重定位?

    为什么需要链接脚本指定地址呢?你想一下,在c语言编程中,当我们需要调用一个A函数的时候,编译器是怎么找到这个A函数?编译器肯定是知道它被放在哪里才可以找到它。...二、重定位需要理解的一些问题。 1、链接地址跟运行地址不同的情况下会出现什么情况?...所以这时候就需要初始化DDR才可,而因为我们知道这代码将来都是在DDR上面运行的,所以链接脚本指定的链接地址肯定是DDR上面的地址,所以这就出现了链接地址跟运行地址不同的情况了。 3、什么是重定位?...答:由于出现1这样的问题,就需要使用重定位这种方式解决上面的问题了。那什么是重定位呢?...4、为什么需要重定位? 答:就是链接地址跟运行地址不同,在这个情况下我们可以有两种方案: ①全部使用位置无关码。 ②进行重定位让这两个地址相同。

    1.9K10

    mysql事务隔离级别可重复读_innodb默认隔离级别

    一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQLServer等,而MySQL却使用可重复读(Read-Repeatable,RR)。...隔离级别依次为>:串行化 > RR > RC >读未提交 在SQL标准中,前三种隔离级别分别解决了幻象读、不可重复读和脏读的问题。那么,为什么MySQL使用可重复读作为默认隔离级别呢?...这个是有历史原因的,要从主从复制开始讲起了! 1.主从复制,是基于什么复制的? 是基于binlog复制的 2.binlog有几种格式?...而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!...因此由于历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题!

    1.3K20

    mysql隔离级别为什么设置为可重复读_隔离性的4个级别

    知识点总结 1.数据库默认隔离级别: mysql —可重复读; oracle,postgres —已提交读 2.mysql binlog的格式三种:statement,row,mixed 3.为什么mysql...用的是可重复读而不是read committed:在 5.0之前只有statement一种格式,而主从复制存在了大量的不一致,故选用repeatable 4.为什么默认的隔离级别都会选用read commited...更重要的是不可重复读问题在开发中是可以接收的,毕竟你数据都已经提交了,读出来本身就没有太大问题 2.在已提交读级别下,主从复制用什么binlog格式:row格式,是基于行的复制!...默认是可重复读” 面试官:“为什么mysql选可重复读作为默认的隔离级别?” (你面露苦色,不知如何回答!) 面试官:"你们项目中选了哪个隔离级别?为什么?" 你:“当然是默认的可重复读,至于原因。。...那么,当我们了解完mysql选可重复读(Repeatable Read)作为默认隔离级别的原因后,接下来我们将其和读已提交(Read Commited)进行对比,来说明为什么在互联网项目为什么将隔离级别设为读已提交

    89410

    面试题66:什么是不可重复读?

    什么是不可重复读 指在一个事务T1内,多次读同一数据。在这个事务T1还没有结束时,另外一个事务T2修改并提交了该同一数据。那么,事务T1两次读到的数据可能是不一样的。...这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。...然后,赶在第二个周末,小丽又约上了她的好姐妹去买包,这次她来到银行,查询账户余额是500块钱,她很开心,钱没有少。...也就是说,重复读取账户的时候,账户余额变化了。这就是不可重复读。 总结 不可重复读发生的核心就是在于小明的整个事务中,可以读到小丽提交了的事务所改变的数据。...可以参见——面试题60:请概述一下,什么是MVCC?那版本链呢?ReadView又有什么用?

    26241

    Mysql为何使用可重复读(Repeatable read)为默认隔离级别?

    群里有小伙伴面试时,碰到面试官提了个很刁钻的问题:Mysql为何使用可重复读(Repeatable read)为默认隔离级别???...等,而MySQL却使用可重复读(Read-Repeatable,RR)。...在Oracle,SqlServer中都是选择读已提交(Read Commited)作为默认的隔离级别,为什么Mysql不选择读已提交(Read Commited)作为默认隔离级别,而选择可重复读(Repeatable...因此由于历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题!...一般是使用mysql自带分布式事务功能时才使用该隔离级别 RC和 RR 此时我们纠结的应该就只有一个问题了:隔离级别是用读已提交还是可重复读?

    1.9K20

    什么是可升级合约

    什么是可升级的智能合约?你可能知道,智能合约是所有可编程区块链(如以太坊上)的一个重要组成部分。通过确保事情按照预定的规则运行,智能合约强制执行秩序。...但是,什么是可升级的智能合约?嗯,首先,你需要注意,在这种情况下,"可升级 "这个词并不意味着可变异。EVM的基本规则之一是,一旦合同被部署,它就不能被改变。相反,可升级的智能合约使用特殊的代理模式。...图片为什么要使智能合约达到可升级智能合约的特点之一就是部署到链上之后不能修改,这一机制使得合约的交互方都可以信任合约。但也带来了一系列的问题,并且如果已部署的合约发现漏洞,也是无法修复的。...有许多代理模式可用,它们可以用来创建可升级的合约。此外,虽然也有很多类型的代理模式,但大多数代理模式都使用transparent 透明代理和UUPS(通用可升级代理标准)。...幸运的是,这两种类型在OpenZeppelin也有提供,这让开发者的工作变得简单了许多。此外,这也是一个捷径,在我们进行一个例子项目时,你会了解更多。

    62130
    领券