MySQL实现事务隔离的秘诀之锁

在MySQL中,有多种锁类型,我们先了解三种概念的锁,以便对接下来的内容有更好理解。

  • 表级锁(Table Lock):对整个表加锁,其他事务无法修改或读取该表的数据,但可以对其他表进行操作。
  • 页级锁(Page Lock):对数据页(通常是连续的几个行)加锁,控制并发事务对该页的访问。适用于数据较大且并发量较高的场景。
  • 行级锁(Row Lock):对单个行加锁,只锁定需要修改的数据行,其他行可以被同时修改或读取。并发性高,但锁管理较复杂。

一般来说,锁的粒度越大,性能就越差。因为粒度一大,那么发生竞争的可能性就越大,进入锁等待的概率也越大。

例如MyISAM引擎主要使用表锁设计,因此它的并发插入性能显然会很慢,因为每次插入都要加表锁,其他对此表进行操作的事务都会受到影响。而SQL Server起初是侧重于页锁,不过后续开始支持行级锁,但因为设计的缘故导致锁的资源很稀有,锁越多开销越大,最后促成锁升级变为表锁。

而InnoDB主要采用行级锁,且行级锁没有相关额外的开销,能够获得很好的并发性。

innoDB的三种行级锁就是本文的重点:行锁(Record Lock)、间隙锁(Gap Lock)、临键锁(Next-Key Lock)。

记录锁(Record Lock)

InnoDB的存储上是一颗聚簇索引树,因此,innoDB的所谓行锁,实际上就是在索引的节点上加锁。记录锁可以防止多个会话同时修改同一条记录,从而保证数据的一致性。

间隙锁(Gap Lock)

用来锁住一个范围内的间隙(即两个索引值之间的空隙),但不包括索引记录本身。

一般情况下,间隙锁是在使用范围查询或者使用唯一索引进行插入时自动创建的。在可重复读(REPEATABLE READ)或者串行化(SERIALIZABLE)的隔离级别下,MySQL会自动创建间隙锁。

间隙锁的存在可以防止幻读问题的产生。由于间隙锁会限制一定范围内的插入操作,避免了其他事务在该范围内插入新的记录,从而保证了一致性。

需要注意的是,间隙锁只锁住范围,并不锁记录本身。

像上图,(E-F)表示锁住E-F之间的记录,但E、F本身并不加锁,如果此时有另外一个事务操作E、F记录是可以成功的,但是如果是在E和F之间插入数据,则会失败。

比较特殊的,由于此时E是最小值,G是最大值,当想锁住比E小的范围时,用(-∞,E)表示;当想锁住比G大的范围时,用(G,+∞)表示。

临键锁

MySQL的临键锁(Next-Key Locks)是一种用于保护事务并发操作的锁机制。它结合了记录锁和间隙锁,能够实现在并发环境下防止幻读的效果。

临键锁的工作原理如下:

  1. 当事务对一个记录进行读取或写入操作时,会对该记录加上记录锁(行锁)。
  2. 若事务需要对一个范围进行操作(比如读取一段记录或者插入新记录),会对这个范围加上间隙锁(区间锁)。
  3. 锁的释放顺序与加锁顺序相反,即先释放间隙锁再释放记录锁。

大白话速记就是:临键锁=记录锁+间隙锁,左开右闭(不锁左边,锁右边)。

临键锁的作用如下:

  1. 防止幻读:在RR(可重复读)隔离级别下,临键锁会对查询范围的间隙进行加锁,以防止其他事务在范围内插入新记录,从而导致幻读现象。
  2. 提高并发度:临键锁的可精确加锁范围带来了更高的并发度,避免了使用传统锁(如表锁、页锁)时的大范围加锁。

不得不多嘴一句,这个临键锁的命名真是太抽象了,刚开始知道的时候,无论如何也不能通过这个名称知道,这是个什么实现。

看到这,可能有人比较疑惑,前面提到的ReadView的存在看起来已经解决了事务隔离,怎么还会有锁的存在?

事实上,ReadView可以理解为第一道关卡,类似于布隆过滤器,如果满足不了ReadView规则的,一定满足不了锁规则;如果满足了ReadView,不一定满足锁。ReadView更多只是从「读」的角度触发,提供一种快速判读的机制,但是解决不了互相写冲突的问题!

因此,锁是一种更为底层同时逻辑偏重的保证机制。

总结:

  • InnoDB有三种锁:记录锁、间隙锁、临键锁。
  • 记录锁只锁住某个具体节点;间隙锁锁住区间但不包含记录本身;临键锁=记录锁+间隙锁,主要用来解决不可重复读的问题

上一篇:诚意满满之MySQL实现事务隔离的秘诀:锁与MVCC

刚好讲到了Record Lock、Gap Lock和Next-Key Lock,那下一篇便讲一讲在实际工作中容易遇到的,如何排查和解决死锁的问题。

欢迎关注~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/750350.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构和算法初阶(C语言)】二叉树铺垫--栈帧的创建与销毁--细节全解

前言: 学习这么久以来,可能有很多疑问:局部变量怎么创建的?为什么局部变量的值是随机的?函数是怎么传参的?传参的顺序是怎么样的?形参和实参是什么样的关系?函数调用是怎么做的&…

由浅到深认识C语言(11):结构体

该文章Github地址:https://github.com/AntonyCheng/c-notes 在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址:https://blog.csdn…

【全开源】JAVA情侣扭蛋机情侣游戏系统源码支持微信小程序+微信公众号+H5

一、功能介绍 会员功能、情侣扭蛋 收到的券、送出的券 合伙代理、意见反馈 我们技术使用JAVA后台服务 前后端分离 springbootmybatisplusmysql 用户端 uniapp(vue语法)管理后台 vueelementUi 适配小程序H5公众号,一套源码,无…

Jenkins 面试题及答案整理,最新面试题

Jenkins中如何实现持续集成与持续部署? Jenkins通过自动化构建、测试和部署应用程序来实现持续集成与持续部署(CI/CD)。这个过程包括以下步骤: 1、源代码管理: Jenkins支持与多种版本控制系统集成,如Git、…

设计模式在芯片验证中的应用——装饰器

一、装饰器模式 装饰器模式(Decorator)是一种结构化软件设计模式,它提供了一种通过向类对象添加行为来修改类对象的方法,而不会影响同一类的其它对象行为。该模式允许在不修改抽象类的情况下添加类功能。它从本质上允许基类代码对不可预见的修改具有前瞻…

SQLiteC/C++接口详细介绍之sqlite3类(十二)

返回目录:SQLite—免费开源数据库系列文章目录 上一篇:SQLiteC/C接口详细介绍之sqlite3类(十一) 下一篇:SQLiteC/C接口详细介绍之sqlite3类(十三) ​37.sqlite3_load_extension 用于在SQLit…

Iframe 嵌入: 页面嵌入并保持自适应页面的宽高并铺满整个屏幕

文章目录 问题分析1. 嵌入 Iframe2. 样式3. 源码 问题 当我们使用 Iframe 嵌入页面后&#xff0c;会看到它只在小小的一部分进行展示&#xff0c;如何让它铺满整个屏幕 分析 1. 嵌入 Iframe <template><div><iframe :src"embeddedPageUrl" width…

R语言中的常用基础绘图函数 直方图,箱线图,条形图,散点图

目录 R语言中的绘图参数 绘图函数 1.plot函数绘制散点图 2.hist函数绘制直方图 如何修饰直方图? 如何在直方图上标注各组频数&#xff1f; 使用text函数把某些信息标注在直方图上 如何在直方图上添加概率密度曲线&#xff1f; 3.boxplot函数绘制箱线图 4.barplot函数…

【强化学习笔记一】初识强化学习(定义、应用、分类、性能指标、小车上山案例及代码)

文章目录 第1章 初识强化学习1.1 强化学习及其关键元素1.2 强化学习的应用1.3 强化学习的分类1.3.1 按任务分类1.3.2 按算法分类 1.4 强化学习算法的性能指标1.5 案例&#xff1a;基于Gym库的智能体/环境接口1.5.1 安装Gym库1.5.2 使用Gym库1.5.3 小车上山1.5.3.1 有限动作空间…

灯塔:CSS笔记(4)

伪类选择器&#xff1a; 1.作用与优势&#xff1a; 1.作用&#xff1a;根据元素在HTML中的结构关系查找元素 2.优势&#xff1a;减少对于HTML中类的依赖&#xff0c;有利于保持代码的整洁 3.场景&#xff1a;常用于查找某父级选择器中的子元素 2.选择器 选择器说明E:first-c…

蓝桥杯2023年省A(一波三折的)【买瓜】折半搜索+剪枝+排序

题目&#xff1a;洛谷 P9234 [蓝桥杯 2023 省 A] 买瓜 折半搜索 一开始觉得像dp&#xff0c;试着写了&#xff0c;显然过不了&#xff0c;但我实在觉得搜索也过不了啊&#xff0c;去看题解&#xff0c;发现使用了折半搜索&#xff08;每天都觉得啥都不会捏 折半搜索就是先搜一…

wayland(xdg_wm_base) + egl + opengles 渲染使用纹理贴图的旋转 3D 立方体实例(十三)

文章目录 前言一、使用 stb_image 库加载纹理图片1. 获取 stb_image.h 头文件2. 使用 stb_image.h 中的相关接口加载纹理图片3. 纹理图片——cordeBouee4.jpg二、渲染使用纹理贴图的旋转 3D 立方体1. egl_wayland_texture_cube.c2. Matrix.h 和 Matrix.c3. xdg-shell-client-pr…

日期与时间(Java)

文章目录 日期与时间&#xff08;Java&#xff09;一、JDK8之前的1.1 Date1.2 SimpleDateFormat1.3 Calendar 二、 JDK8之后的2.1 LocalDate、LocalTime和LocalDateTime2.2 ZoneId和ZonedDateTime2.3 Instant2.4 DateTimeFormatter2.4 Period和 Duration &#x1f389;写在最后…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Web)下篇

onRequestSelected onRequestSelected(callback: () > void) 当Web组件获得焦点时触发该回调。 示例&#xff1a; // xxx.ets import web_webview from ohos.web.webviewEntry Component struct WebComponent {controller: web_webview.WebviewController new web_webv…

Github Copilot 工具,无需账号,一键激活

① 无需账号&#xff0c;100%认证成功&#xff01;0风险&#xff0c;可联网可更新&#xff0c;&#xff0c;支持copilot版本升级&#xff0c;支持chat ② 支持windows、mac、linux系统等设备 ③一号通用&#xff0c;支持所有IDE(AppCode,CLion,DataGrip,GoLand,IntelliJ IDEA …

Linux 基础-查看和设置环境变量

一&#xff0c;查看环境变量 在 Linux中&#xff0c;环境变量是一个很重要的概念。环境变量可以由系统、用户、Shell 以及其他程序来设定&#xff0c;其是保存在变量 PATH 中。环境变量是一个可以被赋值的字符串&#xff0c;赋值范围包括数字、文本、文件名、设备以及其他类型…

前端跨平台开发框架:简化多端开发的利器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

OpenCV系列文章目录(持续更新中......)

引言&#xff1a; OpenCV是一个开源的计算机视觉库&#xff0c;由英特尔公司开发并开源的一组跨平台的C函数和少量的C函数组成&#xff0c;用于实时图像处理、计算机视觉和机器学习等应用领域。OpenCV可以在包括Windows、Linux、macOS等各种操作系统平台上使用&#xff0c;具…

用Origin快速拟合荧光寿命、PL Decay (TRPL)数据分析处理

需要准备材料&#xff1a;Origin、PL Decay数据txt文件 首先打开Origin画图软件 导入数据&#xff0c;按照下图箭头操作直接导入 双击你要导入的PL Decay的txt数据文件&#xff0c;然后点OK 继续点OK 数据导入后首先删除最大光子数之前的无效数据&#xff0c;分析的时候用…

计算机设计大赛 题目:基于机器视觉opencv的手势检测 手势识别 算法 - 深度学习 卷积神经网络 opencv python

文章目录 1 简介2 传统机器视觉的手势检测2.1 轮廓检测法2.2 算法结果2.3 整体代码实现2.3.1 算法流程 3 深度学习方法做手势识别3.1 经典的卷积神经网络3.2 YOLO系列3.3 SSD3.4 实现步骤3.4.1 数据集3.4.2 图像预处理3.4.3 构建卷积神经网络结构3.4.4 实验训练过程及结果 3.5 …