Mysql默认隔离级别为什么是可重复读?

Windows vs Linux 共享内存对比:FileMapping 与 POSIX shm_open 的 5 大差异 本文深入对比了Windows的FileMapping与Linux的POSIX shm_open在共享内存实现上的五大核心差异,包括命名空间机制、内存映射管理、生命周期控制、权限安全模型及错误处理方式。通过详细代码示例和对比表格,帮助开发者理解不同操作系统下进程间通信(IPC)的技术特点,为跨平台系统开发提供实践指导。 阅读详情

知识点总结

1.数据库默认隔离级别: mysql —可重复读; oracle,postgres —已提交读

2.mysql binlog的格式三种:statement,row,mixed

3.为什么mysql用的是可重复读而不是read committed:在 5.0之前只有statement一种格式,而主从复制存在了大量的不一致,故选用repeatable

4.为什么默认的隔离级别都会选用read commited 原因有三:repeatable存在间隙锁会使死锁的概率增大;在可重复读隔离级别下,条件列未命中索引会锁表!而在已提交读隔离级别下,只锁行;在已提交读隔离级别下,引入了半一致性读(semi-consistent)特性增加了update操作的并发性能。更重要的是不可重复读问题在开发中是可以接收的,毕竟你数据都已经提交了,读出来本身就没有太大问题

2.在已提交读级别下,主从复制用什么binlog格式:row格式,是基于行的复制!

引言

开始我们的内容,相信大家一定遇到过下面的一个面试场景

面试官:“讲讲mysql有几个事务隔离级别?”
你:“读未提交,读已提交,可重复读,串行化四个!默认是可重复读”
面试官:“为什么mysql选可重复读作为默认的隔离级别?”
(你面露苦色,不知如何回答!)
面试官:"你们项目中选了哪个隔离级别?为什么?"
你:“当然是默认的可重复读,至于原因。。呃。。。”
(然后你就可以回去等通知了!)

为了避免上述尴尬的场景,请继续往下阅读!
Mysql默认的事务隔离级别是可重复读(Repeatable Read),那互联网项目中Mysql也是用默认隔离级别,不做修改么?
不是的,我们在项目中一般用读已提交这个隔离级别!
what!居然是读已提交,网上不是说这个隔离级别存在不可重复读和幻读问题么?不用管么?好,带着我们的疑问开始本文!

正文

我们先来思考一个问题,在Oracle,SqlServer,postgresql中都是选择读已提交作为默认的隔离级别,为什么Mysql不选择Read Commited作为默认隔离级别,而选择Repeatable Read作为默认的隔离级别呢?
Why?Why?Why?
这个是有历史原因的,当然要从我们的主从复制开始讲起了!
主从复制,是基于什么复制的?
是基于binlog复制的!这里不想去搬binlog的概念了,就简单理解为binlog是一个记录数据库更改的文件吧~
binlog有几种格式?
OK,三种,分别是

  • statement:记录的是修改SQL语句
  • row:记录的是每行实际数据的变更
  • mixed:statement和row模式的混合

那Mysql在5.0这个版本以前,binlog只支持STATEMENT这种格式!而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!
接下来,就要说说当binlog为STATEMENT格式,且隔离级别为读已提交(Read Commited)时,有什么bug呢?如下图所示,在主(master)上执行如下事务
在这里插入图片描述
此时在主(master)上执行下列语句

select * from test;

输出如下

+---+
| b |
+---+
| 3 |
+---+
1 row in set

但是,你在此时在从(slave)上执行该语句,得出输出如下

Empty set

这样,你就出现了主从不一致性的问题!原因其实很简单,就是在master上执行的顺序为先删后插!而此时binlog为STATEMENT格式,它记录的顺序为先插后删!从(slave)同步的是binglog,因此从机执行的顺序和主机不一致!就会出现主从不一致!
如何解决?
解决方案有两种!
(1)隔离级别设为可重复读(Repeatable Read),在该隔离级别下引入间隙锁。当Session 1执行delete语句时,会锁住间隙。那么,Ssession 2执行插入语句就会阻塞住!
(2)将binglog的格式修改为row格式,此时是基于行的复制,自然就不会出现sql执行顺序不一样的问题!奈何这个格式在mysql5.1版本开始才引入。因此由于历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题!

那么,当我们了解完mysql选可重复读(Repeatable Read)作为默认隔离级别的原因后,接下来我们将其和读已提交(Read Commited)进行对比,来说明为什么在互联网项目为什么将隔离级别设为读已提交(Read Commited)!

对比
ok,我们先明白一点!项目中是不用**读未提交(Read UnCommitted)和串行化(Serializable)**两个隔离级别,原因有二

  • 采用读未提交(Read UnCommitted),一个事务读到另一个事务未提交读数据,这个不用多说吧,从逻辑上都说不过去!
  • 采用串行化(Serializable),每个次读操作都会加锁,快照读失效,一般是使用mysql自带分布式事务功能时才使用该隔离级别!(笔者从未用过mysql自带的这个功能,因为这是XA事务,是强一致性事务,性能不佳!互联网的分布式方案,多采用最终一致性的事务解决方案!)

也就是说,我们该纠结都只有一个问题,究竟隔离级别是用读已经提交呢还是可重复读?
接下来对这两种级别进行对比,讲讲我们为什么选读已提交(Read Commited)作为事务隔离级别!
假设表结构如下

 CREATE TABLE `test` (
`id` int(11) NOT NULL,
`color` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB

数据如下

+----+-------+
| id | color |
+----+-------+
|  1 |  red  |
|  2 | white |
|  5 |  red  |
|  7 | white |
+----+-------+

为了便于描述,下面将

  • 可重复读(Repeatable Read),简称为RR;
  • 读已提交(Read Commited),简称为RC;

缘由一:在RR隔离级别下,存在间隙锁,导致出现死锁的几率比RC大的多!
此时执行语句

select * from test where id <3 for update;

在RR隔离级别下,存在间隙锁,可以锁住(2,5)这个间隙,防止其他事务插入数据!
而在RC隔离级别下,不存在间隙锁,其他事务是可以插入数据!

ps:在RC隔离级别下并不是不会出现死锁,只是出现几率比RR低而已!

缘由二:在RR隔离级别下,条件列未命中索引会锁表!而在RC隔离级别下,只锁行
此时执行语句

update test set color = 'blue' where color = 'white'; 

在RC隔离级别下,其先走聚簇索引,进行全部扫描。加锁如下:
在这里插入图片描述
但在实际中,MySQL做了优化,在MySQL Server过滤条件,发现不满足后,会调用unlock_row方法,把不满足条件的记录放锁。
实际加锁如下
在这里插入图片描述
然而,在RR隔离级别下,走聚簇索引,进行全部扫描,最后会将整个表锁上,如下所示在这里插入图片描述
缘由三:在RC隔离级别下,引入半一致性读(semi-consistent)特性增加了update操作的性能!
在5.1.15的时候,innodb引入了一个概念叫做“semi-consistent”,减少了更新同一行记录时的冲突,减少锁等待。
所谓半一致性读就是,一个update语句,如果读到一行已经加锁的记录,此时InnoDB返回记录最近提交的版本,由MySQL上层判断此版本是否满足update的where条件。若满足(需要更新),则MySQL会重新发起一次读操作,此时会读取行的最新版本(并加锁)!
具体表现如下:
此时有两个Session,Session1和Session2!
Session1执行

update test set color = 'blue' where color = 'red'; 

先不Commit事务!
与此同时Ssession2执行

update test set color = 'blue' where color = 'white'; 

session 2尝试加锁的时候,发现行上已经存在锁,InnoDB会开启semi-consistent read,返回最新的committed版本(1,red),(2,white),(5,red),(7,white)。MySQL会重新发起一次读操作,此时会读取行的最新版本(并加锁)!
而在RR隔离级别下,Session2只能等待!

两个疑问

  • 在RC级别下,不可重复读问题需要解决么?
    不用解决,这个问题是可以接受的!毕竟你数据都已经提交了,读出来本身就没有太大问题!Oracle和Postgressql的默认隔离级别就是RC,你们改过他们的默认隔离级别么?

  • 在RC级别下,主从复制用什么binlog格式?
    OK,在该隔离级别下,用的binlog为row格式,是基于行的复制!Innodb的创始人也是建议binlog使用该格式!

总结

本文只是为了说明一件事,互联网项目请用:读已提交(Read Commited)这个隔离级别!

C#中的Chart控件——当数据源很多时可以显示进度条拉动观察,也可以记录到后台文本详细对照 C#中的Chart控件——当数据源很多时可以显示进度条拉动观察,也可以记录到后台文本详细对照下面进行详细步骤说明,感兴趣的同学可以看一下: 1简单示例(一条线): 2.数据源随着时间不断变化,进度条变化 。多条线: 3.看在整段时期内的数据大体图(消去或出现)进度条: 4.后台将时刻记录变化记录到一个txt文本里以供详细校验: 话不多说上码: using System; using Sys... 阅读详情

相关推荐

树莓派 SPI操作

扩展板配备一款0.96inch,128864分辨率的oled显示屏,通过SPI控制,先上显示效果图。由于程序过长,在这里我就不把代码全部贴出来了,只是简单讲解一下spi的操作函数。管脚如下如所有,左边方框的管脚分别为MOSI MISO SCLK,左边CE0,CE1为两个片选管脚,分别对应上图中的spidev0.0,spidev0.1两个设备。下载spidev库,复制到树莓派,并行运行如下命令解压安装。spi设备,此处设备为/dev/spi-decv0.0。在/dev路径下面,我们可以发现两个spi设备。

weixin_46529898的博客 914

mysql -h0 为什么_为啥mysql的默认隔离级别是RR?

Oracle、Sql Server都是RC,为啥偏偏mysql默认是RR?简单自我总结:mysql5.0的redolog是基于statement格式,主从数据库会不一致。一般用RC不用RR,因为不可重复读问题是可以接受的,反正数据都写到数据库了。尽量用RC:RR会引入间隙锁,锁的粒度大,更容易死锁;RR找不到对应列索引会锁表,效率低,RC只会锁行。转自:https://www.cnblogs.co...

weixin_29526539的博客 663

Python实现安居客新房数据抓取简易版

本文介绍使用Python爬取安居客新房楼盘数据的方法,重点针对三四线城市。通过分析移动端H5页面结构,采用滚动加载方式获取推荐楼盘列表(class="recomm-list"),从中提取楼盘ID并拼接详情页链接。代码展示了如何解析HTML标签获取楼盘名称、状态、价格、户型等基本信息,并处理图片URL。爬取过程涉及一个一级页面和两个二级页面,同时提到可能遇到的验证码问题将在后续处理。核心代码使用BeautifulSoup解析HTML,requests发送请求,并将数据存入MySQL数据库。

qq_37604998的博客 473

MySQL使用可重复读作为默认隔离级别的原因之一

一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQLServer等,而MySQL却使用可重复读(Read-Repeatable,RR)。要知道,越高的隔离级别,能解决的数据一致性问题越多,理论上性能损耗更大,可并发性越低。隔离级别依次为 SERIALIZABLE>RR>RC>Read-Uncommited 在SQL标准中,前三种隔离级别分别解决了幻象读、不可重复读和脏读的问题。那么,为什么MySQL使用可重复读...

渔夫数据库笔记 1051

2026年9月20日 2026年CSP-S初赛真题整理

这是本次考试最难的部分,涉及Gray Code(格雷码)+ 状态压缩 + 数学推导难点解决方案关键代码问题转化将得分差转化为m−2xim - 2x[i]m−2xi高效枚举Gray Code相邻状态O(1)转移奇偶判断利用奇偶性统一条件。

weixin_51184047的博客 619

鸿蒙进阶——HDI及IDL硬件接口IPC框架小结

HDI(Hardware Device Interface):OpenHarmony硬件设备接口,定义系统中跨进程通信的接口,实现服务间的跨进程通信

最美不过,心中有梦,身旁有你! 3900

mysql数据库的默认隔离级别为什么是可重复读

目录 一 mysql的主从复制 二 当mysql数据库的隔离级别为“读提交”时: 三 当mysql默认隔离级别为可重复读时 总结: 一 mysql的主从复制 1 主服务器上面的任何操作都会通过自己的 I/O tread(I/O 线程)保存在二进制日志Binary log里面。 2 从服务器上面也启动一个 I/O thread,通过配置好的用户名和密码, 连接...

只布布倩 2410

ADS基础教程16 - 存档和导入(workspace、cell、view)

选择workspace_Archive目录作为保存workspace归档的目录,点击打开进行目录选择,点击Finish保存目录。,选择cell_Archive目录作为保存cell归档的目录,点击打开进行目录选择,点击Finish保存目录。,选择view_Archive目录作为保存view归档的目录,点击打开进行目录选择,点击Finish保存目录。(2)在弹框中,可以选择点击Select将参考的条目添加进来,然后点击Next…(2)在弹框中,可以选择点击Select将参考的条目添加进来,然后点击Next…

XZ_ZC的博客 3699

为什么 MySQL 事务默认隔离级别是可重复读?

MySQL 默认的隔离级别是可重复读( Repeatable Read ),即 RR。

codenav的博客 807

【100%通过率】华为OD机试真题 Python 实现【网上商城优惠活动 / 模拟商场优惠打折II】

某网上商场举办优惠活动,发布了满减、打折、无门槛3种 优惠券,分别为: 1:每满100元优惠10元,无使用数限制,如100~199元可以使用1张减10元,200~299可使用2张减20元,以此类推; 2:92折券,1次限使用1张,如100元,则优惠后为92元, 3:无门槛5元优惠券,无使用数限制,直接减5元。

MISAYAONE的博客 9369

小龙虾们的好伙伴专栏导航

本文系统解析了OpenClaw技术架构,包括Channel层和网关层的设计实现,并与AgentSkills等技术方案进行对比。同时提供了OpenClaw的系列实用指南,涵盖小龙虾培养、客户资源管理、系统自动化巡检以及技术趋势助手构建等应用场景,帮助用户从零成本入门到高效落地应用,实现业务全流程自动化管理。

wend的博客 209

为什么mysql默认隔离级别设置为可重复读

一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQLServer等,而MySQL却使用可重复读(Read-Repeatable,RR)。要知道,越高的隔离级别,能解决的数据一致性问题越多,理论上性能损耗更大,可并发性越低。隔离级别依次为>:串行化 > RR > RC >读未提交 在SQL标准中,前三种隔离级别...

码农之道 8325

【WRF数据介绍第二期】气象驱动场数据介绍及下载

【WRF数据介绍第二期】气象驱动场数据介绍及下载

WW、forever的博客 2160

MySQL 默认隔离级别为何选择可重复读(REPEATABLE READ)

数据库隔离级别是事务并发控制的核心,定义了事务之间如何隔离以保证数据一致性。读未提交(READ UNCOMMITTED):允许读取未提交数据,可能导致脏读。读已提交(READ COMMITTED):只读取已提交数据,避免脏读,但可能出现不可重复读。可重复读(REPEATABLE READ):事务内多次读取相同数据结果一致,避免脏读和不可重复读,部分避免幻读。可序列化(SERIALIZABLE):事务串行执行,避免所有并发问题,但性能最低。脏读:读取未提交且可能回滚的数据。不可重复读。

lssffy的博客 1794

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

MySQL为什么默认设置为可重复读隔离级别?

实际生产环境中,绝大多数 OLTP 系统(如:订单系统、库存系统、会员系统)对一致性要求很高,但又不能忍受过低的并发性能。而 Repeatable Read 隔离级别,能让绝大部分常见业务在保持较高一致性的同时,还能支持高并发访问。完全串行化的 Serializable 代价太高,大量锁等待,TPS 下降严重,不符合业务需求。虽然最严格,但强制事务串行执行,严重降低了并发性能,不适合高并发 OLTP 系统。,通过 MVCC 机制,事务只读取开始时的快照,自动避免了幻读。虽然并发性更高,但容易出现。

weixin_46072507的博客 927

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【MYSQL】InnoDB引擎为什么选可重复读作为默认隔离级别

一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQL Server等,而MySQL却使用可重复读(Read-Repeatable,RR)。要知道,越高的隔离级别,能解决的数据一致性问题越多,理论上性能损耗更大,可并发性越低。隔离级别依次为InnoDB引擎选可重复读作为默认隔离级别主要是解决主从同步不一致的问题。

xiazi0721的博客 1421

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

数据库-Mysql为何使用可重复读(Repeatable read)为默认隔离级别?可重复读RR没什么必要,推荐用读已提交RC

先看另一篇博客,可重复读其实没啥必要。而且一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQL Server等,而MySQL却使用可重复读(Read-Repeatable,RR)。要知道,越高的隔离级别,能解决的数据一致性问题越多,理论上性能的损耗更大,且并发性越低。隔离级别依次为: SERIALIZABLE > RR > RC > RU为什么mysql要这样呢在读已提交(Read Commited)级别下,出现不可重复读问题怎么办?

S_ZaiJiangHu的博客 986

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

一.基本概念 1. mysql的事务隔离级别有哪些? 1.Read Uncommitted(读取未提交内容) 未提交读 2.Read Committed(读取提交内容) 已提交读 3.Repeatable Read(可重读) 可重复读 4.Serializable(可串行化) 可串行化 spring的事务隔离级别 也是这四种. 它默认数据库是什么级别,自己就是什么级别. 2. 什么是脏读 不可重复读 幻读 1、 脏读:A,B两事务,A事务

启迪思维,精进技术 1020

MySQL默认事务隔离级别大揭秘:可重复读(REPEATABLE READ)为什么是王者?

MySQL演化路径早期MySQL的存储引擎(如MyISAM)不支持事务,InnoDB引入事务后选择了与Oracle不同的默认级别,形成了差异化特色维度优势价值一致性无脏读/不可重复读数据可靠性能MVCC优化高并发兼容性历史行为一致平滑升级灵活性支持当前读业务适配终极建议🔄默认使用可重复读- 除非有明确需求变更⚠️警惕长事务- 会导致版本链膨胀🔍理解业务需求- 是选择隔离级别的第一准则行动指南并根据业务特点决定是否需要调整,欢迎在评论区分享你的实战经验!🚀。

全栈开发工程师 1437

mysql隔离级别为什么设置为可重复读_MySQL使用可重复读作为默认隔离级别的原因...

一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQL Server等,而MySQL却使用可重复读(Read-Repeatable,RR)。要知道,越高的隔离级别,能解决的数据一致性问题越多,理论上性能损耗更大,可并发性越低。隔离级别依次为SERIALIZABLE > RR > RC > Read-Uncommited在...

weixin_32459553的博客 716

MySQL使用可重复读作为默认隔离级别的原因

一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQLServer等,而MySQL却使用可重复读(Read-Repeatable,RR)。要知道,越高的隔离级别,能解决的数据一致性问题越多,理论上性能损耗更大,可并发性越低。隔离级别依次为 SERIALIZABLE>RR>RC>Read-Uncommite...

XiaoGong1688的博客 333

为什么mysql选可重复读作为默认的隔离级别

Mysql默认的事务隔离级别是可重复读(Repeatable Read),那互联网项目中Mysql也是用默认隔离级别,不做修改么? OK,不是的,我们在项目中一般用读已提交(Read Commited)这个隔离级别! 1.为什么mysql选可重复读作为默认的隔离级别 在RR级别下,binlog为任何格式均不会造成主从数据不一致的情况出现,但是当低版本MySQL使用RC+STATEMENT组合时(MySQL5.1.5前只有statement格式)将会导致主从数据不一致。当前这个历史遗漏问题以及解决,大家可以将

思凡 1868

MySQL使用可重复读作为默认隔离级别的原因(一)

一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQL Server等,而MySQL却使用可重复读(Read-Repeatable,RR)。要知道,越高的隔离级别,能解决的数据一致性问题越多,理论上性能损耗更大,可并发性越低。隔离级别依次为 SERIALIZABLE &gt; RR &gt; RC &gt; Read-Uncommite...

qq_2300688967的博客 2113

mysql默认隔离级别为什么是可重复读,业务代码为什么设置为读已提交

Mysql隔离级别为什么默认可重复读 这主要是由于历史原因造成的,mysql的主从复制是基于binlog复制的。 binlog的三种格式 1.statement:记录的是修改SQL语句 2.row:记录的是每行实际数据的变更 3.mixed:statement和row模式的混合 那Mysql在5.0及这个版本以前,binlog只支持STATEMENT这种格式!而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的(主从不一致问题,就是在master上执行的顺序为先删后插!而此时

weixin_43892390的博客 1560

为什么mysql默认RR(repeat read可重复读)隔离级别

mysql隔离级别

qq_41067796的博客 1050

mysql可重复读 默认锁_MySQL使用可重复读作为默认隔离级别的原因之一

一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQLServer等,而MySQL却使用可重复读(Read-Repeatable,RR)。要知道,越高的隔离级别,能解决的数据一致性问题越多,理论上性能损耗更大,可并发性越低。隔离级别依次为SERIALIZABLE>RR>RC>Read-Uncommited在...

weixin_39564853的博客 237
上一篇: ThreadLocal
下一篇: 来说一说你对锁都怎么分类?
余生之君
博客等级 码龄10年 246粉丝 98原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值