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

news2024/11/26 1:50:09

在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.coloradmin.cn/o/1522787.html

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

相关文章

SLAM 算法综述

LiDAR SLAM 其主要思想是通过两个算法:一个高频激光里程计进行低精度的运动估计,即使用激光雷达做里程计计算两次扫描之间的位姿变换;另一个是执行低频但是高精度的建图与校正里程计,利用多次扫描的结果构建地图,细化位…

切面条-蓝桥杯?-Lua 中文代码解题第1题

切面条-蓝桥杯?-Lua 中文代码解题第1题 一根高筋拉面,中间切一刀,可以得到2根面条。 如果先对折1次,中间切一刀,可以得到3根面条。 如果连续对折2次,中间切一刀,可以得到5根面条。 那么&#xf…

【QT入门】VS2019+QT的开发环境配置

声明:该专栏为本人学习Qt知识点时候的笔记汇总,希望能给初学的朋友们一点帮助(加油!) 往期回顾: 【QT入门】什么是qt,发展历史,特征,应用,QtCreator-CSDN博客【QT入门】Windows平台下…

Java设计模式 | 设计模式概述和分类

独孤求败五重境界 利剑(“凌厉刚猛,无坚不摧,弱冠前以之与河朔群雄争锋。”)软剑(“紫薇软剑,三十岁前所用,误伤义士不祥,乃弃之深谷。”)重剑(“重剑无锋&a…

React 实现下拉刷新效果

简介 本文基于react实现下拉刷新效果,在下拉的时候会进入loading状态。 实现效果 效果如上图所示,在下拉到底部时候,会出现loading条,在处理完成后loading条消失。 具体代码 布局 & 逻辑 import {useRef, useState} from …

【IC设计】Verilog线性序列机点灯案例(二)(小梅哥课程)

文章目录 该系列目录:设计目标设计思路RTL 及 Testbench仿真结果存在的问题?改善后的代码RTL代码testbench代码 仿真结果 案例和代码来自小梅哥课程,本人仅对知识点做做笔记,如有学习需要请支持官方正版。 该系列目录:…

javaEE——线程的等待和结束

文章目录 Thread 类及常见方法启动一个线程中断一个线程变量型中断调用 interrupt() 方法来通知观察标志位是否被清除 等待一个线程获取当前线程引用休眠当前线程 线程的状态观察线程的所有状态观察 1: 关注 NEW 、 RUNNABLE 、 TERMINATED 状态的切换 多线程带来的风险为什么会…

Ubuntu 14.04:安装 PaddleOCR 2.3

目录 一、说明 1.1 如何选择版本 1.2 查看 github 中的 PaddleOCR 版本 二、安装 2.1 安装前环境准备 2.2 下载包 2.3 解压 2.4 安装依赖库 异常处理:Read timed out. 2.5 下载推理模型:inference 2.5.1 模型存放位置 2.5.2 模型下载链接 2.5.…

【5G NB-IoT NTN】3GPP R17 NB-IoT NTN介绍

博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客…

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

返回目录:SQLite—免费开源数据库系列文章目录 上一篇:SQLiteC/C接口详细介绍之sqlite3类(九) 下一篇:​​SQLiteC/C接口详细介绍之sqlite3类(十一) 30.sqlite3_enable_load_extension&#x…

Docker 学习笔记一

一、什么是docker Docker 是一个基于轻量级虚拟化技术的容器,整个项目基于Go语言开发;Docker是一个C/S架构,后端众多模块各司其职,docker的daemon是运行在主机上通过client可以进行通信。 docker 由三部分组成:镜像(…

读算法的陷阱:超级平台、算法垄断与场景欺骗笔记12_移动平台(上)

1. 广告 1.1. 广告收入的来源 1.1.1. 向客户推荐广告投放网址 1.1.2. 提供有效提高产品广告点击率的咨询服务 1.1.3. 从合作伙伴的广告收入中捞上一笔 1.2. 对于广告主来讲,他们无意于与各家网站逐一谈判 1.2.1. 这种方式一是成本过高,二是费时费力…

C#控制台贪吃蛇

Console.Write("");// 第一次生成食物位置 // 随机生成一个食物的位置 // 食物生成完成后判断食物生成的位置与现在的蛇的身体或者障碍物有冲突 // 食物的位置与蛇的身体或者障碍物冲突了,那么一直重新生成食物,直到生成不冲突…

算法——前缀和之除自身以外数组的乘积、和为K的子数组、和可被K整除的子数组、连续数组、矩阵区域和

这几道题对于我们前面讲过的一维、二维前缀和进行了运用,包含了面对特殊情况的反操作 目录 4.除自身以外数组的乘积 4.1解析 4.2题解 5.和为K的子数组 5.1解析 5.2题解 6.和可被K整除的子数组 6.1解析 6.2题解 7.连续数组 7.1题解 7.2题解 8.矩阵区域和 8.1解析 …

在pharmit里匹配药效团

我把400个无活性的小分子(decoys)提交到pharmit里。 命名为decoyset00~decoyset08,查找时,按这个找。 1、导入药效团配体: 进入药效团筛选界面: 导入代表药效团模型的活性肽构象: 2、选择预先…

搞机笔记 MI8 dipper

刷回MIUI 之前刷了 lineage-19.1-20220728-nightly-dipper-signed 基于安卓12,实现了以下功能 TWRPmagisk & ROOTmicroG 退回MIUI的原因有: lineage 墓碑 管不住APP后台,太卡了MIUI提供了3GB的虚拟内存lineage 不支持人脸识别lineag…

【基础CSS】

本文章属于学习笔记&#xff0c;在https://www.freecodecamp.org/chinese/learn/2022/responsive-web-design/中练习 二、 CSS 样式&#xff0c;新建一个文件.css&#xff0c;该文件不含有style标签 <style>. h1&#xff0c;h2&#xff0c;p{ text-align&#xff1a;ce…

[长城杯 2021 院校组]funny_js

[长城杯 2021 院校组]funny_js 审题 根据题名提示为js&#xff0c;再在ida中查看&#xff0c;基本可以确定为quickjs题 QuickJS 是一个快速、灵活且易于嵌入的 JavaScript 引擎&#xff0c;适用于需要在资源受限环境下运行 JavaScript 代码的场景。 工具准备 来到Linux&…

Linux学习方法-框架学习法——Linux系统框架

配套视频学习链接&#xff1a;https://www.bilibili.com/video/BV1HE411w7by?p2&vd_sourced488bc722b90657aaa06a1e8647eddfc 目录 Linux系统框架(从裸机到OS) Linux可看成是一个大软件/大程序 应用和驱动 内核态和用户态 Linux的文件系统 Linux初学者首先要搞清楚三…

第二门课:改善深层神经网络<超参数调试、正则化及优化>-超参数调试、Batch正则化和程序框架

文章目录 1 调试处理2 为超参数选择合适的范围3 超参数调试的实践4 归一化网络的激活函数5 将Batch Norm拟合进神经网络6 Batch Norm为什么会奏效&#xff1f;7 测试时的Batch Norm8 SoftMax回归9 训练一个SoftMax分类器10 深度学习框架11 TensorFlow 1 调试处理 需要调试的参…