当前位置: 首页 > news >正文

MySQL锁机制

前置

锁理论

锁总结

锁实践

记录锁

间隙锁

临键锁

对数据库的操作有读、写,组合起来就有 读读、读写、写读、写写,读读不存在安全问题,安全问题加锁都可以解决,但所有的操作都加锁太重了,只有写写必须要求加锁,读写、写读可以用MVCC。MySQL的默认隔离级别是RR,但是RR在MVCC的加持下还是存在幻读,这时候就还是需要加锁,间隙锁就是用来在RR级别下解决幻读的问题。

共享锁、排他锁

共享锁(shared lock )也叫读锁、S锁,数据被某个事务获取了共享锁之后,还可以被其它事务获取共享锁,但是不能被其它事务获取排他锁。

排他锁(exclusive Lock)也叫写锁、X锁,数据被某个事务获取之后就不能被其它事务获取任何锁。

总结:共享锁和共享锁之间不冲突,排他锁和共享锁、排他锁都冲突。默认select的时候是不加锁的,更新、添加、删除的时候会加排他锁。

强制加共享锁 lock in share mode ,强制加排他锁 for update

select * from my_table where id = 1 lock in share mode;
select * from my_table where id = 1 for update;

意向锁:意向共享锁、意向排他锁

加锁的时候可能锁某一行或几行的数据,也可能锁整个表,但上面共享锁只能和共享锁兼容,排他锁和两者都不兼容。虽然锁表的场景很少,如果要用共享锁锁表不得一行行去遍历看看数据有没有被排他锁锁过,如果要用排它锁锁表就得一行行去遍历看是否存在数据被共享锁或排他锁占用。

实际上是不可能遍历的,代价太大,所以在对某些数据加共享锁的时候,就会给表加上 意向共享锁,对某些数据加排他锁的时候就会对表加上 意向排他锁。

这样再对表加锁的时候只需要判断是否有对应的意向锁就好了,而不需要遍历。意向锁之间是不冲突的。

共享锁(S)、排他锁(X)、意向共享锁(IS)、意向排他锁(IX)的兼容关系
在这里插入图片描述
记录锁、间隙锁、临键锁

前置

上面说了一些锁的概念,现在来尝试一下给数据加锁,在正式开始之前需要了解一下MySQL的数据存储结构:

在主键索引形成的B+Tree里面,非叶子结点存储的是主键索引,叶子结点存储的是数据
在非主键索引形成的B+Tree里面,非叶子结点存储的是当前索引,叶子结点存储的是主键索引
如果没有主键索引,会拿第一个唯一索引来做聚簇索引,如果也没有唯一索引就会创建一个看不见的唯一键。
所以当通过非主键索引去找数据的时候,其实是先通过非主键索引找到主键索引,再通过主键索引去找数据,这个过程被称为 回表。

锁理论

记录锁(Record Locks):记录锁是基于索引记录上的锁,它锁定的行数是固定的、明确的,根据情况它可以是共享锁、排他锁。间隙锁(Gap Locks):间隙锁的目的是在RR级别下,防止幻读,幻读的产生是当前事务多次的查询结果数量上不一致,间隙锁的目的就是保证当前范围内的数据不会被更改,所以它会锁住某些个区间的数据。临键锁(Next-key Locks):等于 记录锁+间隙锁,所以我们只需要知道这两个锁的定义就好了,MySQL默认级别是RR、默认锁上临键锁。

锁总结

锁都是基于索引去找到数据记录再加锁的,而索引的规则是:通过其它索引找到主键索引,所以:

没有使用索引做更新相关操作会锁表。
通过唯一/主键索引等值加锁,只会锁具体的行,非唯一索引则不一定,SQL优化器会基于数据分布选择记录锁,或临键锁。
只有在RR级别下才有间隙锁,目的是为了解决幻读,如果操作的数据是跨多个范围,就会加多个区间的间隙锁。
MySQL默认的锁就是【临键锁】,所以在执行SQL的时候,记录锁和间隙锁是会同时存在的。范围是左开右闭的区间。
在SQL查询的时候,我们知道是先通过索引去找数据的,其实加锁也是基于索引的,通过索引找到对应的数据然后把相关的数据行都锁上,如果没有使用索引就会扫描全表,也就会锁表。

锁实践

基于上面的理论和总结,我们用实际的SQL来证明一下,加深印象。

记录锁
创建一个表,并往里面塞一些数据,然后来验证

CREATE TABLE `xdx_lock` (`id` int NOT NULL COMMENT '主键索引',`conutry` varchar(255) NOT NULL COMMENT '唯一索引',`name` varchar(255) NOT NULL COMMENT '普通索引',`age` int NOT NULL COMMENT '不是索引',PRIMARY KEY (`id`),UNIQUE KEY `conutry_idx` (`conutry`),KEY `name_idx` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='锁表测试'

在这里插入图片描述
间隙锁
让我们再来回忆一下,间隙锁的目的是为了防止幻读,所以间隙锁的目的就是阻止一切会让当前事务数据量变化的操作。

MySQL的数据存储是B+Tree,以主键建立的B+Tree。我们假设表的数据有5条,它们的id分别是 5,10,15,20,25 (这种数据很有可能对吧),虽然它是树结构,但也是排好序的,并且就是以主键为排序的。

间隙锁的原理就是锁住我们查询数据的各种区间,可能不好理解,先举几个例子:

where id > 9, 它锁住的区间就是 (5, +∞) , 开头是5不是9哦,因为9这玩意不存在呀,基于索引加锁,没有索引无法加锁
where id > 9 and id < 18, 它锁住的区间就是 (5, 10]、(10, 15]、(15, 20]
where id = 10,它只会锁住 10 这一条数据
where id = 7,因为7不存在,为了防止后续新增,所以也要锁住最近的一个区间 (5, 10]
注:间隙锁 是左开右开的区间,但间隙锁和临键锁一起的,而临键锁是左开右闭。

CREATE TABLE `xdx_lock_new` (`id` INT   NOT NULL    COMMENT '主键' ,`name` VARCHAR(255)   NOT NULL    COMMENT '普通数据' ,PRIMARY KEY  (`id`)  
);INSERT INTO `xdx_lock_new`(`id`, `name`) VALUES ('5', 'java');
INSERT INTO `xdx_lock_new`(`id`, `name`) VALUES ('10', 'c');
INSERT INTO `xdx_lock_new`(`id`, `name`) VALUES ('15', 'go');
INSERT INTO `xdx_lock_new`(`id`, `name`) VALUES ('20', 'lua');
INSERT INTO `xdx_lock_new`(`id`, `name`) VALUES ('25', 'js');

where id > 9
在这里插入图片描述
where id > 9 and id < 18
在这里插入图片描述
where id = 10
在这里插入图片描述
where id = 7
在这里插入图片描述
锁非唯一索引
基于唯一索引或主键索引,间隙锁的范围很好理解,但是基于非唯一索引进行数据锁定的时候,SQL优化器最终执行的结果可能和我们想象的并不一样。比如下面这个案例,相同的SQL,但是表数据不一样的时候,直接结果也不一样。

CREATE TABLE `xdx_lock_normal_primary` (`id` int(11) NOT NULL,`name` varchar(255) NOT NULL,`age` int(11) NOT NULL,PRIMARY KEY (`id`),KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

结果一
在这里插入图片描述
结果二

在这里插入图片描述
总结

来看一下GPT的回答,我觉得应当是如此的,简单来说就是查询优化器觉得不需要间隙锁了,直接转成具体的记录锁。
在这里插入图片描述
注:在第一种情况下,的确是因为加了间隙锁导致的,因为间隙锁的目的是防止幻读,是在RR级别下的,当我把全局事务改成RC的时候,第一种数据集也不会锁 3、4 两行数据。

但其实这也不是必然的,在MySQL5.8和5.7里面的结果是不一样的
在这里插入图片描述
临键锁
MySQL默认的锁就是临键锁,当写一个SQL的时候就有可能触发临键锁,但临键锁并不是一个单独的锁,临键锁 = 记录锁 + 间隙锁,所以分析的时候我们可以单独的判断它当前加了那种记录锁,然后再单独看它是否被加了间隙锁,再结合起来判断。

表锁、页面锁、行锁
在学习MySQL锁的时候这些锁给我带来了很大的困扰,其实它们只是表示我们当前这次操作锁了多少数据而已,比是一行数据还是整个表的数据。

MySQL官方文档里面并未对这几个锁做出解释。

死锁

死锁其上并不属于MySQL锁的范围,它只是基于锁而产生的一种现象
在这里插入图片描述

相关文章:

MySQL锁机制

前置 锁理论 锁总结 锁实践 记录锁 间隙锁 临键锁 对数据库的操作有读、写&#xff0c;组合起来就有 读读、读写、写读、写写&#xff0c;读读不存在安全问题&#xff0c;安全问题加锁都可以解决&#xff0c;但所有的操作都加锁太重了&#xff0c;只有写写必须要求加锁&…...

webpack loader

1、分类 2、执行顺序 配置类型 执行顺序是 loader1>loader2>loader3 3、使用方式 自己的第一个loader 同步loader /*** loader 就是一个函数* 当webpack 解释资源时&#xff0c; 会调用相应的loader去处理* loader 接收到文件内容作为参数&#xff0c;返回文件内容* p…...

Java—学生信息管理系统(简单、详细)

文章目录 一、主界面展示二、学生类三、系统功能方法3.1 main()方法3.2 添加学生信息3.3 删除学生信息3.4 修改学生信息3.5 查看所有学生信息 四、完整代码4.1 Student .Java4.2 StudentManger.Java 前言&#xff1a;本案例在实现时使用了Java语言中的ArrayList集合来储存数据。…...

Spring第一课,了解IDEA里面的文件,回顾Cookie和Session,获取Session,Cookie,Header的方式

目录 IDEA第一课&#xff08;熟悉里面内容&#xff09; 建立连接 -RequestMapping 路由映射 请求 1.传递单个参数​编辑 2.多个参数​编辑 3.传递数组 4.传递一个集合&#xff0c;但是这里我们传递的时候发生了500的错误 简单介绍JSON 回顾Cookie和S…...

AcWing113.特殊排序

题目 有 N N N 个元素&#xff0c;编号 1 , 2.. N 1,2..N 1,2..N&#xff0c;每一对元素之间的大小关系是确定的&#xff0c;关系具有反对称性&#xff0c;但不具有传递性。 注意&#xff1a;不存在两个元素大小相等的情况。 也就是说&#xff0c;元素的大小关系是 N N N…...

数据仓库岗面试

1.自我介绍 2.求用户连续登录3天&#xff0c;要讲出多种解法 解法1&#xff08;使用SQL&#xff09;&#xff1a; SELECTuserid FROMloginrecord WHEREDATEDIFF(day, time, LAG(time) OVER (PARTITION BY userid ORDER BY time)) 1AND DATEDIFF(day, LAG(time) OVER (PARTI…...

企业建数仓的第一步是选择一个好用的ETL工具

当企业决定建立数据仓库&#xff08;Data Warehouse&#xff09;&#xff0c;第一步就是选择一款优秀的ETL&#xff08;Extract, Transform, Load&#xff09;工具。数据仓库是企业数据管理的核心&#xff0c;它存储、整合并管理各种数据&#xff0c;为商业决策和数据分析提供支…...

行情分析 - - 加密货币市场大盘走势(11.23)

大饼昨日又开始了回调&#xff0c;因为FTF消息&#xff0c;而实际还是要下跌的&#xff0c;耐心等待即可。 空单策略&#xff1a;入场37300 止盈34000-33000 止损39000 以太昨日上涨也很激励&#xff0c;目前上涨打了止损&#xff0c;现在入场是好的机会&#xff0c;等待即可。…...

穿山甲SDK 集成·android接入广告·app流量变现

接入穿山甲SDK的app 数独训练APP 广告接入示例: Android 个人开发者如何接入广告SDK&#xff0c;实现app流量变现 接入穿山甲SDK app示例&#xff1a; android 数独小游戏 经典数独休闲益智 随着移动互联网的快速发展&#xff0c;广告成为了许多应用开发者获取收益的主要方…...

深度学习模型训练计算量的估算

深度学习模型训练计算量的估算 方法1&#xff1a;基于网络架构和批处理数量计算算术运算次数前向传递计算和常见层的参数数量全连接层&#xff08;Fully connected layer&#xff09;参数浮点数计算量 CNN参数浮点数计算量 转置CNN参数浮点数计算量 RNN参数浮点数计算量 GRU参数…...

【实验笔记】C语言实验——降价提醒机器人

降价提醒机器人 题目&#xff1a; 小 T 想买一个玩具很久了&#xff0c;但价格有些高&#xff0c;他打算等便宜些再买。但天天盯着购物网站很麻烦&#xff0c;请你帮小 T 写一个降价提醒机器人&#xff0c;当玩具的当前价格比他设定的价格便宜时发出提醒。 输入格式&#xf…...

YOLOv5分割训练,从数据集标注到训练一条龙解决

最近进行了分割标注&#xff0c;感觉非常好玩&#xff0c;也遇到了很多坑&#xff0c;来跟大家分享一下&#xff0c;老样子有问题评论区留言&#xff0c;我会的就会回答你。 第一步&#xff1a;准备数据集 1、安装标注软件labelme如果要在计算机视觉领域深入的同学&#xff0…...

再添千万级罚单,某银行年内罚款过亿!金融行业合规问题亟待解决

11月17日晚间&#xff0c;国家金融监管总局上海监管局披露行政处罚信息显示&#xff0c;某银行因32项违法违规事实收到两张690万元的大额罚单&#xff0c;合计罚款金额达1380万元。但这并不是银行该今年收到的第一张大额罚单。今年4月28日&#xff0c;该行因在结售汇、外币理财…...

配置Nginx服务器用于Web应用代理和SSL{仅配置文件}

在本篇博文中&#xff0c;我们将深入讨论如何配置Nginx服务器&#xff0c;使其成为一个强大的Web应用代理&#xff0c;并通过SSL协议加强通信的安全性。 1. 服务器监听与SSL设置 首先&#xff0c;我们要配置Nginx服务器以监听HTTPS流量并设置SSL证书&#xff0c;确保通信的安…...

【广州华锐互动】VR溺水预防教育:在虚拟世界中学会自救!

在现代社会中&#xff0c;水上安全和救援行动的重要性不言而喻。尤其在自然灾害、游泳事故或航海事故中&#xff0c;有效的救援行动可以挽救许多生命。然而&#xff0c;传统的救援训练往往存在成本高、风险大、效率低等问题。在这样的背景下&#xff0c;虚拟现实&#xff08;VR…...

Si(111)衬底上脉冲激光沉积AlN外延薄膜的界面反应控制及其机理

引言 通过有效控制AlN薄膜与Si衬底之间的界面反应&#xff0c;利用脉冲激光沉积&#xff08;PLD&#xff09;在Si衬底上生长高质量的AlN外延薄膜。英思特对PLD生长的AlN/Si异质界面的表面形貌、晶体质量和界面性能进行了系统研究。 我们研究发现&#xff0c;高温生长过程中形…...

基于Cortex®-M4F的TM4C123GH6NMRT7R 32位MCU,LM74900QRGERQ1、LM74930QRGERQ1汽车类理想二极管

一、TM4C123GH6NMRT7R IC MCU 32BIT 256KB FLASH 157BGA Tiva™C系列微控制器为设计人员提供了基于ARMCortex™-M的高性能架构&#xff0c;该架构具有广泛的集成功能以及强大的软件和开发工具生态系统。以性能和灵活性为目标&#xff0c;Tiva™C系列架构提供了一个具有FPU的80…...

苹果企业签名失败常见的问题

苹果企业签名失败的常见问题主要有以下几种&#xff1a; 证书过期或无效&#xff1a;苹果开发者需要定期更新他们的签名证书&#xff0c;以确保其有效性。一旦证书过期&#xff0c;相关应用将无法正常工作。证书不匹配&#xff1a;如果使用的证书与应用程序的Bundle ID不匹配&…...

Jtti:Android alertdialog嵌套出错怎么解决

在Android开发中&#xff0c;AlertDialog嵌套可能导致一些问题&#xff0c;例如显示异常或无法关闭对话框等。这通常是由于上一个AlertDialog未被正确关闭&#xff0c;导致下一个AlertDialog无法正常工作。解决这个问题的方法包括&#xff1a; 1. 确保关闭上一个AlertDialog&a…...

解锁word密码,忘记密码怎么办?

想要解密、找回或去除Word文档密码&#xff0c;可以按以下步骤操作&#xff1a;第一步&#xff0c;在百度上搜索【密码帝官网】&#xff0c;接着在用户中心上传需要解密的文件即可。这种方法安全、简单易操作&#xff0c;而且不用下载软件&#xff0c;手机和电脑都可以用。无论…...

OpenMMReasoner框架:多模态模型训练与强化学习优化

1. OpenMMReasoner框架设计解析OpenMMReasoner的核心创新在于构建了一个端到端的透明化训练框架&#xff0c;将监督微调(SFT)和强化学习(RL)两个阶段有机整合。这个框架的设计源于我们在实际训练大型多模态模型时遇到的三个关键挑战&#xff1a;数据质量瓶颈&#xff1a;现有开…...

Java开发者如何通过Taotoken快速接入多模型API服务

Java开发者如何通过Taotoken快速接入多模型API服务 1. 准备工作 在开始集成Taotoken的多模型API服务前&#xff0c;需要确保开发环境满足基本要求。Java项目建议使用JDK 11或更高版本&#xff0c;并准备好构建工具如Maven或Gradle。Taotoken平台采用OpenAI兼容协议&#xff0…...

别再傻傻分不清了!嵌入式开发中UART、SPI、I2C到底怎么选?附Arduino/STM32实战对比

嵌入式开发实战&#xff1a;UART、SPI、I2C协议选型指南 在嵌入式系统开发中&#xff0c;选择合适的通信协议往往决定了项目的成败。面对琳琅满目的传感器、显示屏和功能模块&#xff0c;新手工程师常被UART、SPI、I2C这三种主流串行通信协议搞得晕头转向。本文将从实际项目需求…...

终极Visual C++运行库修复指南:从问题诊断到自动化运维全攻略

终极Visual C运行库修复指南&#xff1a;从问题诊断到自动化运维全攻略 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist VisualCppRedist AIO是一个强大的开源工具…...

LinkSwift网盘直链下载助手:一键获取八大网盘下载链接的终极指南

LinkSwift网盘直链下载助手&#xff1a;一键获取八大网盘下载链接的终极指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云…...

Aeona框架深度解析:构建Discord AI聊天机器人的架构设计与实战

1. 项目概述&#xff1a;Aeona&#xff0c;一个被低估的AI聊天机器人框架如果你在GitHub上搜索过“Discord bot”或者“AI chatbot”&#xff0c;大概率会刷到过deepsarda/Aeona这个仓库。乍一看&#xff0c;它可能只是又一个基于Discord.js的机器人项目&#xff0c;但当你真正…...

GL.iNet Beryl AX便携式路由器评测:WiFi 6与OpenWrt的完美结合

1. GL.iNet Beryl AX 便携式路由器深度评测作为一名长期关注网络设备的科技博主&#xff0c;我有幸拿到了GL.iNet最新推出的Beryl AX&#xff08;GL-MT3000&#xff09;便携式路由器。这款支持WiFi 6的小巧设备给我留下了深刻印象&#xff0c;它不仅具备2.5GbE高速网口&#xf…...

【Swoole+LLM长连接生产落地白皮书】:20年架构师亲授高并发、低延迟、零断连的5大核心部署法则

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;SwooleLLM长连接架构全景与生产价值定位 Swoole 作为高性能 PHP 协程引擎&#xff0c;结合大语言模型&#xff08;LLM&#xff09;的流式推理能力&#xff0c;可构建低延迟、高并发、全双工的智能会话服…...

B站视频下载的3步智能解决方案:告别网络限制,高效管理你的学习资源

B站视频下载的3步智能解决方案&#xff1a;告别网络限制&#xff0c;高效管理你的学习资源 【免费下载链接】bilibili-downloader B站视频下载&#xff0c;支持下载大会员清晰度4K&#xff0c;持续更新中 项目地址: https://gitcode.com/gh_mirrors/bil/bilibili-downloader …...

LLM服务性能压测实战:从原理到工具应用与优化分析

1. 项目概述&#xff1a;为什么我们需要一个专业的LLM性能测试工具&#xff1f; 在部署和优化大语言模型服务时&#xff0c;我们经常会遇到一些灵魂拷问&#xff1a;我的服务器到底能扛住多少并发请求&#xff1f;响应延迟的瓶颈在哪里&#xff1f;是GPU算力不足&#xff0c;还…...