MySQL中的意向锁 + next-key锁 + 间隙锁

引言

在数据库并发控制中,锁机制是保障数据一致性和隔离性的核心手段。MySQL中意向锁、间隙锁以及next-key锁等复杂锁类型,旨在协调表级锁与行级锁之间的关系,防止数据的脏读、不可重复读和幻读现象,尤其是在可重复读隔离级别下发挥关键作用。然而,锁机制在提升数据隔离性的同时,也可能带来死锁风险和写倾斜问题,影响系统的并发性能和业务逻辑正确性。本文将系统梳理MySQL中意向锁与next-key锁的原理及应用,剖析间隙锁导致的死锁现象,并结合实际案例探讨写倾斜问题及其解决方案,帮助读者深入理解数据库锁机制与事务隔离的内在联系。

意向锁

主要作用是协调表锁与行锁之间的互斥关系。意向锁本身之间是不会发生冲突的,与行级别的共享锁(S 锁)和排他锁(X 锁)也不发生冲突。它们主要与表级别的共享锁(S 锁)和排他锁(X 锁)发生冲突,在表级别加锁时提升效率,避免全表扫描来判断是否有行锁存在。

  • 意向共享锁(IS, Intention Shared Lock):当事务打算对表中的某些行加共享锁(S 锁)时,必须首先对该表加一个意向共享锁(IS 锁),告诉其他想锁表的事务该表有行数据加了共享锁。
  • 意向排他锁(IX, Intention Exclusive Lock):当事务打算对表中的某些行加排他锁(X 锁)时,必须首先对该表加一个意向排他锁(IX 锁),告诉其他想锁表的事务该表有行数据加了排他锁。

next-key Lock的理解

next-key Lock = gap Lock + row Lock,只在可重复读隔离级别存在。

  • 对主键或唯一索引,如果当前读时,where条件全部精确命中(=或者in),这种场景本身就不会出现幻读,只会加行记录锁。如果查询未精准命中,查询了不存在的值,会产生间隙锁。例如:[1, 5, 10]。select * from table where id=3; 会对(1, 5)(左开右开)加上锁。
  • 没有索引的列,当前读操作时,会加全表gap锁,生产环境要注意。
  • 非唯一索引列,如果where条件部分命中(>、<、like等)或者全未命中,则会加附近gap间隙锁。例如,某表数据如下,非唯一索引[2、6、9、9、11、15]。要操作非唯一索引列 9 的数据(select * from table where x = 9 for update),gap锁将会锁定的列是(6, 11](左开右闭),该区间内无法插入数据。
  • 主键或唯一索引,范围查询时会对查找范围内的间隙上锁,例如,唯一索引[1、5、10、15]。where id>1 and id<10 for update,gap锁会对(1,10)(左开右开),该区间会加锁。

next-key Lock无法解决的幻读

next-key Lock可以解决当前读下的幻读问题,但引入了死锁问题。next-key Lock无法解决当前读隔离级别下的幻读问题。

间隙锁导致的死锁问题

间隙锁之间不互斥,间隙锁和写锁之间是互斥的。

写倾斜问题

当两个或多个并发事务读取相同的数据并基于这些读取的结果执行写操作时,因为这些事务在执行过程中彼此不可见,最终可能导致违反数据一致性或业务逻辑的结果。

举个例子

假设,医院调度系统,每个医生在一天内只能处理最多 10 个病人。

  • 事务 A 和事务 B 都读取到医生1的病人数量是 9。
  • 事务 A 判断病人数量小于 10,因此增加一个病人,病人数量变为 10,并提交事务。
  • 事务 B 仍然认为病人数量是 9(因为它读取时事务 A 尚未提交),也增加一个病人,病人数量变为 11,并提交事务。
#表结构
CREATE TABLE doctor_patients (doctor_id INT,patient_count INT,PRIMARY KEY (doctor_id)
);#事务A
START TRANSACTION;
SELECT patient_count FROM doctor_patients WHERE doctor_id = 1;  -- 读取到的病人数量是 9
-- 逻辑判断:如果病人数量小于10,则增加一个病人
UPDATE doctor_patients SET patient_count = patient_count + 1 WHERE doctor_id = 1;
COMMIT;#事务B
START TRANSACTION;
SELECT patient_count FROM doctor_patients WHERE doctor_id = 1;  -- 读取到的病人数量也是 9(因为事务 A 尚未提交)
-- 逻辑判断:如果病人数量小于10,则增加一个病人
UPDATE doctor_patients SET patient_count = patient_count + 1 WHERE doctor_id = 1;
COMMIT;

解决办法

  • 开启串行化隔离级别,事务A对行数据加共享锁,事务B也可以对行数据加共享锁。事务A修改行数据时发现事务B加了共享锁只能阻塞,事务B修改行数据时发现事务A加了共享锁此时产生了死锁。保证了不会产生锁倾斜问题。
  • 读数据时加上for update,保证其他事务无法读取这行数据。

感谢您的阅读!如果文章中有任何问题或不足之处,欢迎及时指出,您的反馈将帮助我不断改进与完善。期待与您共同探讨技术,共同进步!

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

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

相关文章

机器学习 数据集

数据集 1. scikit-learn工具介绍1.1 scikit-learn安装1.2 Scikit-learn包含的内容 2 数据集2.1 sklearn玩具数据集介绍2.2 sklearn现实世界数据集介绍2.3 sklearn加载玩具数据集示例1&#xff1a;鸢尾花数据示例2&#xff1a;分析糖尿病数据集 2.4 sklearn获取现实世界数据集示…

Linux-c语言串口程序

c语言串口程序 // C library headers #include <stdio.h> #include <string.h>// Linux headers #include <fcntl.h> // Contains file controls like O_RDWR #include <errno.h> // Error integer and strerror() function #include <termios.h&g…

TCP IP

TCP/IP 通信协议&#xff0c;不是单一协议&#xff0c;是一组协议的集合 TCP IP UDP 1.建立链接 三次握手 第一步&#xff1a;客户端发送一个FIN报文&#xff0c;SEQX,等待服务器回应 第二步&#xff1a;服务器端受到&#xff0c;发送ackx1,seqy, 等待客户端回应 第三步&am…

用uniapp在微信小程序实现画板(电子签名)功能,使用canvas实现功能

效果&#xff1a; 功能&#xff1a;实现重签 退出 保存 等功能 解决的问题: 电子签名画布抖动问题解 注意&#xff1a; 保存的时候上传到自己的服务器地址&#xff0c;后端返回图片地址 代码&#xff1a; <template><view><view class"signature&qu…

机器学习经典算法:用决策树原理优化新能源汽车续航能力

🔥 “用决策树重构新能源车能量大脑!算法推导+代码实战全解,续航暴增15%” 决策树算法就像我们生活中做决策的 “流程指南”,通过层层判断得出最终结论。比如你去超市买水果,站在琳琅满目的货架前,就不自觉地用上了决策树思维。首先,你可能会想 “今天想吃酸的还是甜的…

【Unity中的数学】—— 四元数

一、四元数的定义&#x1f60e; 四元数是一种高阶复数&#xff0c;是一个四维空间的概念&#xff0c;相对于复数的二维空间。它可以表示为 q s i x j y k z q s ix jy kz qsixjykz&#xff0c;其中 s s s、 x x x、 y y y、 z z z 都是实数&#xff0c;并且满足 i …

macOS 15.4.1 Chrome不能访问本地网络

前言 最近使用macmini m4&#xff0c;自带macOS15系统&#xff0c;对于开发者简直是一言难尽&#xff0c;Chrome浏览器的本地网络有bug&#xff0c;可以访问本机&#xff0c;但是不能访问路由器上的其他机器&#xff0c;路由器提供的页面也不能访问&#xff0c;如下是折腾解决…

浏览器刷新结束页面事件,调结束事件的接口(vue)

浏览器刷新的时候&#xff0c;正在进行中的事件结束掉&#xff0c;在刷新浏览器的时候做一些操作。 如果是调接口&#xff0c;就不能使用axios封装的接口&#xff0c;需要使用原生的fetch。 找到公共的文件App.vue 使用window.addEventListener(‘beforeunload’, function (e…

TCP/IP 模型每层的封装格式

TCP/IP 模型是一个四层网络架构&#xff0c;每一层在数据传输时都会对数据进行封装&#xff0c;添加相应的头部&#xff08;和尾部&#xff09;信息。以下是各层的封装格式及关键字段说明&#xff1a; 1. 应用层&#xff08;Application Layer&#xff09; 封装格式&#xff1a…

【行业深度解析】什么是马甲包?

在 Android 应用分发和增长运营的实践中&#xff0c;“马甲包” 是一个常被提及的策略术语。特别是在 Google Play 平台上&#xff0c;许多开发者或运营团队出于营销、风险分摊或生态布局等原因&#xff0c;会选择通过发布“马甲包”来实现多元化的业务拓展。 然而&#xff0c…

谷歌与微软的AI战争:搜索、云服务与生态布局

谷歌与微软的AI战争&#xff1a;搜索、云服务与生态布局 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 谷歌与微软的AI战争&#xff1a;搜索、云服务与生态布局摘要引言技术路线对比1. AI基础设施&#xff1a;算力…

uniapp自定义导航栏搭配插槽

<uni-nav-bar dark :fixed"true" shadow background-color"#007AFF" left-icon"left" left-text"返回" clickLeft"back"><view class"nav-bar-title">{{ navBarTitle }}</view><block v-slo…

无人机飞控算法开发实战:从零到一构建企业级飞控系统

简介 无人机飞控算法是实现稳定飞行和精确控制的核心技术,涉及飞行动力学建模、传感器数据处理、状态估计和控制策略等多个环节。本实战指南将系统讲解四旋翼无人机飞控算法的开发流程,包括飞行动力学模型建立、传感器校准与数据融合、主流控制算法实现(PID、ADRC、EKF)以…

p2p虚拟服务器

ZeroTier Central ✅ 推荐工具&#xff1a;ZeroTier&#xff08;免费、稳定、跨平台&#xff09; ZeroTier 可以帮你把多台设备&#xff08;无论是否跨网&#xff09;加入一个虚拟局域网&#xff0c;彼此间可以像在同一个 LAN 中通信&#xff0c;UDP 视频、文件传输、SSH 等都…

MySQL数据库迁移SQL语句指南

MySQL数据库迁移SQL语句指南 一、基础迁移方法 1. 使用mysqldump进行全量迁移 -- 导出源数据库&#xff08;在命令行执行&#xff09; mysqldump -u [源用户名] -p[源密码] --single-transaction --routines --triggers --events --master-data2 [数据库名] > migration…

画立方体软件开发笔记 js three 投影 参数建模 旋转相机 @tarikjabiri/dxf导出dxf

gitee&#xff1a; njsgcs/njsgcs_3d mainwindow.js:4 Uncaught SyntaxError: The requested module /3dviewport.js does not provide an export named default一定要default吗 2025-05-10 14-27-58 专门写了个代码画立方体 import{ scene,camera,renderer} from ./3dviewp…

【工具】HandBrake使用指南:功能详解与视频转码

HandBrake使用指南&#xff1a;功能详解与视频转码 一、前言 高清视频在当下日益普及&#xff0c;从影视制作到个人拍摄&#xff0c;从社交媒体发布到远程教育&#xff0c;如何高效地压缩、转换和管理视频文件的体积与清晰度&#xff0c;成为内容创作者与技术开发者的核心任务…

Docker容器网络架构深度解析与技术实践指南——基于Linux内核特性的企业级容器网络实现

第1章 容器网络基础架构 1 Linux网络命名空间实现原理 1.1内核级隔离机制深度解析 1.1.1进程隔离的底层实现 通过clone()系统调用创建新进程时&#xff0c;设置CLONE_NEWNET标志位将触发内核执行以下操作&#xff1a; 内核源码示例&#xff08;linux-6.8.0/kernel/fork.c&a…

SAP 交货单行项目含税金额计算报cx_sy_zerodivide处理

业务背景&#xff1a;SAP交货单只有数量&#xff0c;没有金额&#xff0c;所以开发报表从订单的价格按数量计算交货单的金额。 用户反馈近期报表出现异常&#xff1a; ****2012/12/12 清风雅雨 规格变更 Chg 修改开始 ** 修改原因:由于余数为0时&#xff0c;可能会报错溢出。…

【高数上册笔记01】:从集合映射到区间函数

【参考资料】 同济大学《高等数学》教材樊顺厚老师B站《高等数学精讲》系列课程 &#xff08;注&#xff1a;本笔记为个人数学复习资料&#xff0c;旨在通过系统化整理替代厚重教材&#xff0c;便于随时查阅与巩固知识要点&#xff09; 仅用于个人数学复习&#xff0c;因为课…