mysql InnoDB引擎各种隔离级别的加锁机制

news2025/1/15 6:35:21

文章目录

    • 概要
    • 前置知识了解
    • 各种隔离锁的验证
    • 小结

概要

我们都知道,mysql的InnoDB引擎在各种隔离级别下的加锁机制都是有差异的,但是对于各种隔离级别下如何加锁大家可能不太了解,今天我就通过一篇文章去带领大家去分析一下各个隔离级别的加锁过程,如果有误,欢迎大家在评论区指正!

今天实验的表结构定义如下,欢迎大家自己去尝试验证。我的mysql版本是5.7。其中id加上了唯一索引为了验证行锁的加锁过程。age加上非唯一索引,给大家演示一下gap的加锁过程。:

-- 学生表,id,姓名,年纪三个字段。
CREATE TABLE `t_stu` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '商品ID',
  `name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '会员卡名称',
  `age` int NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  KEY `name` (`name`),
  KEY `age` (`age`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=78 DEFAULT CHARSET=utf8mb3 COMMENT='会员商品表';

INSERT INTO `t_stu` (`id`, `name`, `age`) VALUES (1, '小张', 1);
INSERT INTO `t_stu` (`id`, `name`, `age`) VALUES (3, '小王', 3);
INSERT INTO `t_stu` (`id`, `name`, `age`) VALUES (4, '小美', 4);
INSERT INTO `t_stu` (`id`, `name`, `age`) VALUES (44, '小美', 44);

前置知识了解

读锁和写锁的互斥情况,只有读锁和读锁可以并行执行,其他的情况都是互斥的。

读锁写锁
读锁x
写锁xx
  • mysql的表级锁有哪些,其中我们需要重点关注的就是元数据锁:
    1. 表锁:通常意义上我们是不会给表主动加锁。通过 LOCK TABLES t_stu READ,LOCK TABLES t_stu WRITE去加锁。通过unlock tables去解锁。在实际的业务过程中题主暂时未遇到过使用场景,所以这个锁不在我们的讨论范围。
    2. 元数据锁(MDL):这个锁我们需要关注一下,我们在表结构变更时会加一个MDL写锁,就是当我们操作表做DDL语句时,例如:给表加字段,给表加索引。当我们给做crud语句时会给表加MDL读锁。所以在高并发的场景下,不可以去对表做DDL操作,会锁表。 因为DDL语句不会被事物控制,所以对于小批量的数据题主没办法演示加锁情况,大家可以自行多加点数据去做演示。
    3. 意向锁:题主没关注这个。
    4. AUTO-INC 锁:主键索引自增时加的一个锁。

  • mysql的行锁有哪些:
    1. 行级锁: 加在索引上的锁,如果表上没有任何索引,InnoDB会使用一个内部的行ID来锁定行。在RR隔离级别下,我们在没有索引的表上去修改数据,其实是锁定了所有的行+加上行的间隙,并不是锁表。
    2. 间隙锁 GAP LOCK: 间隙锁是RR隔离级别下加在非唯一索引的两个数据之间的锁,注意是非唯一索引,理论上我们对主键索引去修改数据时是不会加间隙锁的。注意间隙锁只有在RR隔离级别下才存在。
    3. next-key lock: 行级锁+间隙锁组成的锁。

各种隔离锁的验证

  • 读未提交 (READ UNCOMMITTED): 按照顺序执行,我们会发现事物2在执行到第四步时被阻塞了,说明在读未提交的情况下是有行级锁存在的。并不是网上说的行级锁只存在于读已提交和可重复读的隔离级别。
-- 事物1 ----------------------------------------------------------
-- 1
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN;
-- 3
UPDATE `t_stu` SET `name` = 'aa' WHERE `id` = 1;
COMMIT;


-- 事物2 ----------------------------------------------------
-- 2
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN;
-- 4
UPDATE `t_stu` SET `name` = 'aaa' WHERE `id` = 1;
COMMIT;

通过命令查看加锁状态,可以看到数据都被加了X锁,就是排它锁。
在这里插入图片描述
在这里插入图片描述

  • 读已提交 (READ COMMITTED):
-- 事物1 ----------------------------------------------------------
-- 1
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN;
-- 3
-- UPDATE `t_stu` SET `name` = 'aa' WHERE `id` = 1;
SELECT * FROM `t_stu` WHERE age = 4 LOCK IN SHARE MODE;
-- 5
SELECT * FROM `t_stu` WHERE age = 4 LOCK IN SHARE MODE;
-- 7
COMMIT;

-- 事物2 ----------------------------------------------------
-- 2
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN;
-- 4
INSERT INTO `jl`.`t_stu` (`id`, `name`, `age`) VALUES (10, '小小美', 4);
-- 6
COMMIT;

注意这块的查询语句我加上了S共享锁,因为mysql默认查询时SELECT语句是默认不加锁的,所以为了方便演示我加上了读共享锁。上述语句我们在执行时,是能成功的插入数据的,通过锁分析也可得知在RC隔离级别下,对于普通索引的数据我们只加了行级锁,但是没有加gap lock的。当我们执行到步骤5,第六步未执行的情况下,我们看一下加锁状态,写请求加了X排它锁,读数据我加了共享锁。所以从分析就可以得知在RC隔离级别下,就算是普通的非唯一索引age,也不会加gap锁。

在这里插入图片描述

  • 可重复读 (REPEATABLE READ):
-- 事物1 ----------------------------------------------------------
-- 1
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
-- 3
-- UPDATE `t_stu` SET `name` = 'aa' WHERE `id` = 1;
SELECT * FROM `t_stu` WHERE age = 4 LOCK IN SHARE MODE;
-- 5
SELECT * FROM `t_stu` WHERE age = 4 LOCK IN SHARE MODE;
-- 7
COMMIT;

-- 事物2 ----------------------------------------------------
-- 2
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
-- 4
INSERT INTO `jl`.`t_stu` (`id`, `name`, `age`) VALUES (10, '小小美', 4);
-- 6
COMMIT;

当我们在执行步骤4时其实就会被阻塞了,数据是没办法插入成功的,因为此时在age的的非唯一索引上加了age=4的数据的行级别锁,在非主键键索引上在age(3,4)(4,44)之间加了gap lock。导致了数据插入时就会锁冲突,没办法进行数据插入。
在这里插入图片描述
我们在演示一个其他的例子,我们把上面事物2的插入的id为10的age数据改成64。先看一数据库的数据:
在这里插入图片描述

-- 事物2 ----------------------------------------------------
-- 2
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
-- 4
INSERT INTO `jl`.`t_stu` (`id`, `name`, `age`) VALUES (10, '小小美', 64);
-- 4
-- 6
COMMIT;

最终发现,执行到步骤4时,数据是可以插入成功的,那就是因为,我们age为64的数据不在gap锁锁定age的范围(3,4),(4,44)范围内。

小结

通过上面的各种的案例演示,给大家展示了各种隔离级别下的数据的加锁状态。可能有些知识点是打破可大家对于加锁状态的认知的,大家可以通过本地数据库去模拟一下各种隔离级别的数据加锁状态,会加深大家对于这些知识的认知:行锁什么时候加,gap锁什么时候加,gap锁的锁定范围这些

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

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

相关文章

【HTML】使用Javascript制作网页

1、Javascript的语法规则 JavaScript程序按照在HTML文件中出现的顺序逐行执行。JavaScript严格区分字母大小写。在JavaScript中,每行结尾的分号可有可无。JavaScript中主要包括两种注释:单行注释和多行注释。单行注释使用双斜线“//”作为注释标签&…

AI绘画商业实战,深入剖析Stable Diffusion 服装模特精准换装脱Y,AI虚拟模特变现教程

大家好,我是灵魂画师向阳 在之前的文章中,我们已经深入讲解了SD与ControlNet基础知识和原理。接下来我们将结合这一堆基础工具法宝组合使用,完成一些有意义的AIGC商业实战案例分享。 本文是来自一位粉丝的现实需求案例:电商服装…

人在上海ip显示在安徽怎么回事?怎么办

在这个信息爆炸的时代,网络已成为我们生活中不可或缺的一部分。无论是工作、学习还是娱乐,网络都以其独特的魅力渗透进我们生活的每一个角落。然而,随着网络技术的不断发展,一些看似不可思议的现象也逐渐浮出水面。比如&#xff0…

海思SD3403/SS928V100开发(16)Tsensor驱动开发

1. 前言 由于需要检测SD3403芯片内部实时温度,需要开发Tsensor传感器驱动和应用 查看手册发现SD3403内部有三个Tsensor传感器 可以参考之前我写的35系列平台Tsensor驱动开发记录 海思35系列平台Tsensor驱动开发(1)驱动编写_t sensor-CSDN博客 海思35系列平台Tsensor驱动…

什么是埋点测试,app埋点测试怎么做?

前言 埋点测试是指在应用程序或网站中预设检查点,收集程序运行时的数据,以便于后续对程序进行性能分析或故障排查。埋点测试通常用于监控和追踪用户在软件产品中的行为,以收集有关用户体验、功能使用情况和潜在问题的数据。这些数据对于软件…

哪些ai取名网站免费?盘点4大好用的ai取名字自动生成器

在忙碌而喧嚣的都市生活中,越来越多人选择养宠物作为自己的精神寄托。当你决定迎接一只新生命回家时,除了准备好食物等必需品外,更重要的是给它起一个既好听又有意义的名字。 然而,有时候想出一个合适的名字并不容易,…

中电金信:稳定运行超百天!业内首个100%全栈国产化手机银行上线

日前,国内首个全栈国产化手机银行-华润银行新一代手机银行已经正式投产超百天,系统运行稳定,性能显著提升,客户体验明显改善,达成了“新理念、新体验、新技术、新底座”的建设目标,整体水平处于行业中上游。…

对射式光电开关应用

图 5-38a所示是自动启停扶梯的示意图。扶梯入口安装一个对射式光电开关,当有人走到扶梯口要上扶梯时,挡住了光电开关发光部分所发出的光,使得受光部分无法接收到光信号,由此控制扶梯启动,延时一段时间后,扶…

ubuntu上cmake3.30.2的安装

引言 安装下载安装包将安装包从windows拷贝到ubuntu解压进入解压后的文件夹执行boostrap编译CMake安装CMake查看是否安装成功 目前的ubuntu系统是20.04.4,用命令行安装了cmake的版本是3.16的,由于项目需要升级cmake到cmake3.22之上,使用命令行…

揭秘led台灯对眼睛好不好?护眼台灯真的护眼吗?台灯要这样选!

在当今数字化时代,长时间面对电脑屏幕和各种电子设备已成为日常生活的一部分,这对我们的视力构成了前所未见的挑战。目前中国的近视情况十分严峻,尤其在青少年群体中表现得更为突出。因此,科学用眼、合理安排用眼时间和增加户外活…

新手起步:探索AWS新账户的服务器部署能力与限制

对于刚刚注册Amazon Web Services (AWS)账户的用户来说,一个常见的疑问是:我能立即开始部署服务器吗?这个问题的答案是肯定的,但同时也需要注意一些重要的细节。我们九河云将深入探讨新注册的AWS账户在服务器部署方面的能力和注意…

AI大模型应用开发实战-Agent应用对话情感优化

1 使用prompt设计agent性格与行为 添加系统 prompt: 代码语言:python 代码运行次数:0 复制 Cloud Studio 代码运行 self.SYSTEMPL """你是一个非常厉害的算命先生,你叫JavaEdge人称Edge大师。以下是你的个人…

数据库MySQL多表设计、查询

目录 1.概述 2.一对多 3.一对一 4.多对多 5.多表查询 5.1内连接 5.2外连接 5.3子查询 1.概述 项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个…

信息集成系统:打造智慧化的数字化平台

在现代社会中,信息集成系统已经成为不可或缺的一部分。它们不仅可以帮助企业管理各种数据和资源,还可以提供更高效的工作流程和更好的用户体验。本文将介绍信息集成系统的定义、优势、应用以及最新的技术趋势。 什么是信息集成系统?它是一种集…

2024年【甘肃省安全员C证】考试题及甘肃省安全员C证考试总结

题库来源:安全生产模拟考试一点通公众号小程序 甘肃省安全员C证考试题考前必练!安全生产模拟考试一点通每个月更新甘肃省安全员C证考试总结题目及答案!多做几遍,其实通过甘肃省安全员C证模拟试题很简单。 1、【多选题】《安全生产…

统信UOS系统访问windows共享目录

问题背景 当我们使用UOS系统的时候,想要访问windows系统的一些资料并将其拷贝下来使用的话,应该怎么操作呢?这个需求是可以实现的,统信UOS系统是基于Linux系统开发的,Linux系统和windows系统之间可以通过SMB协议来共享…

C++重要语法一图概括(复习用)

0.思维导图 1.传值返回和引用返回 1.1传值返回 传值返回所返回的是当前对象的拷⻉ 1.2引用返回 引⽤返回返回的是对象本身, 返回对象是⼀个局部变量,出了作⽤域便会 被销毁, 所以不可使⽤引⽤返回 出了作⽤域,引⽤对象还在,才可以引⽤返回 所以说如果⼀个变量⽣命周期只在…

嵌入式面试八股文(四)·同步和互斥、同步和异步、同步阻塞和同步非阻塞、异步阻塞和异步非阻塞的详细分析

目录 1. 同步和互斥 1.1 同步 1.2 互斥 1.3 总结 2. 同步和异步 2.1 同步 2.2 异步 3. 阻塞和非阻塞 3.1 阻塞 3.2 非阻塞 4. 同步阻塞和同步非阻塞 4.1 同步阻塞 4.2 同步非阻塞 4.3 同步阻塞和同步非阻塞的区别 5. 异步阻塞和异步非阻塞 5.1 …

基于微信小程序的学生宿舍管理系统设计与实现

宿舍管理 | 学生宿舍 | 学生宿舍管理 | 学生宿舍管理小程序 博主介绍:✌️大家好!我是Coder-coco,一名专注以理论为基础、实战为主的技术博主,本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目&a…

使用html2canvas将网页导出为图片

1. 安装html2canvas npm install html2canvas或者 pnpm install html2canvas2. 简单使用案例 ref:Vue 3 的 ref 用来引用 DOM 元素。我们通过 exportContent 引用需要导出的 DOM 元素。 html2canvas:html2canvas 库会将指定的 DOM 元素渲染为画布&…