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

MySQL 中的锁机制详解:原理、实现方式与实战解析!

🚀MySQL 中的锁机制详解:原理、实现方式与实战解析!

锁的世界,比你想象得更精彩!

一、为什么要有锁?

在并发环境下,多线程操作数据库的同一份数据时,如果没有锁机制,可能会出现以下问题:

  • 脏读:读取了另一个事务未提交的数据。
  • 不可重复读:同一事务中多次读取结果不一致。
  • 幻读:读取时发现记录“凭空”出现或消失。

锁的存在,就是为了保证并发情况下的数据一致性与隔离性


二、MySQL 中锁的分类

1. 按作用范围分类

分类说明
全局锁(Global Lock)对整个数据库加锁,一般用于全库备份
表级锁(Table Lock)针对整张表加锁,粒度较大
行级锁(Row Lock)针对数据行加锁,粒度最小,性能最好,但实现最复杂

2. 按加锁方式分类

类型示例说明
共享锁(S锁)SELECT ... LOCK IN SHARE MODE允许多个事务同时读,不允许写
排他锁(X锁)SELECT ... FOR UPDATE其他事务不能读写
意向锁(IS/IX锁)系统自动加辅助锁,表级声明“我想要对某行加锁”

3. 按存储引擎支持分类

存储引擎锁类型特性
MyISAM表级锁写阻塞读,读也阻塞写
InnoDB行级锁 + 表级锁 + 意向锁支持事务,支持多版本并发控制(MVCC)

三、InnoDB 的锁实现机制详解

1. 行锁的实现 —— 基于索引实现

❗注意:InnoDB 的行锁是加在索引上的,而不是行数据本身!

  • 如果没有走索引,会退化为表锁
  • 使用主键或唯一索引时,锁的粒度最小。
  • 非唯一索引或范围查询时,可能触发间隙锁(Gap Lock)临键锁(Next-Key Lock)

2. 锁的类型:Gap Lock、Next-Key Lock、Record Lock

类型锁定对象应用场景
Gap Lock索引之间的间隙,不含记录本身防止幻读
Record Lock精确锁定某一行WHERE id = 1
Next-Key LockGap Lock + Record Lock范围查询:WHERE id > 10 AND id < 20

3. 意向锁的作用

意向锁是表级的,辅助事务判断是否可以加表锁。

  • IS:意向共享锁
  • IX:意向排他锁

🧠 不会阻塞其它行锁,但可以提高加锁效率


四、加锁语句实践讲解

1. 显式加锁

-- 加共享锁
SELECT * FROM users WHERE id = 1 LOCK IN SHARE MODE;-- 加排他锁
SELECT * FROM users WHERE id = 1 FOR UPDATE;

2. 隐式加锁(通过事务自动加锁)

START TRANSACTION;
UPDATE users SET name = '张三' WHERE id = 1;
-- 自动加X锁
COMMIT;

3. 范围锁示例

-- 假设id上有索引
SELECT * FROM users WHERE id BETWEEN 10 AND 20 FOR UPDATE;
-- 实际锁住:记录10~20之间所有行 + 所在间隙

五、MySQL 锁常见问题解析

1. 为什么 update 语句会锁多行?

因为你的 WHERE 条件可能是范围查询,比如:

UPDATE users SET status = 'active' WHERE score > 80;

👉 会触发 Next-Key Lock 锁住符合范围的所有行+间隙。

2. 如何查看当前锁情况?

-- 查看 InnoDB 锁信息
SELECT * FROM information_schema.INNODB_LOCKS;
SELECT * FROM information_schema.INNODB_LOCK_WAITS;

3. 死锁如何避免?

  • 控制事务粒度,越小越好。
  • 所有事务按照相同顺序加锁
  • 使用短事务
  • 避免大事务长时间持锁。

六、实战演练:模拟死锁

-- 会话1:
BEGIN;
UPDATE account SET balance = balance - 100 WHERE id = 1;-- 会话2:
BEGIN;
UPDATE account SET balance = balance - 200 WHERE id = 2;-- 会话1:
UPDATE account SET balance = balance + 100 WHERE id = 2; -- 阻塞-- 会话2:
UPDATE account SET balance = balance + 200 WHERE id = 1; -- 死锁!

🎯 解决方式:加锁顺序保持一致!


七、引流文案建议(适合CSDN/掘金)

🔥 你真的了解 MySQL 锁吗?为什么 update 有时候卡住?死锁频频出现,根源在哪?一文彻底搞懂 MySQL 锁机制,从底层原理到实战演练,助你迈向高级工程师之路!


八、总结

锁类型粒度并发性实现方式
表锁MyISAM
行锁InnoDB(基于索引)
Gap Lock间隙锁防幻读Next-Key Lock 衍生

🔚 锁是一把双刃剑:加得对,性能飞起;加得错,性能雪崩!

http://www.lqws.cn/news/530209.html

相关文章:

  • MySQL多表关系
  • Nordic 电源管理nPM1300 EK评估板介绍
  • 大模型在慢性病毒性肝炎预测及诊疗方案制定中的应用研究
  • 频宽是什么: 0.35/Tr、0.5/Tr?
  • 第七章---软件实现与编码
  • 关于 ARM64 汇编:调用流程与栈帧结构解析
  • 酒店智能门锁系统常见问题解决方法——东方仙盟
  • zookeeper总是重启失败
  • Golang是什么
  • AI代码编程工具:开启智能编程新时代
  • uniapp微信小程序:editor组件placeholder字体样式修改
  • Spring Boot 中使用 Jackson 实现全局时间格式处理(支持多格式反序列化)
  • A模块 系统与网络安全 第三门课 网络通信原理
  • Spring AI 入门到实战:我如何用它让系统具备“理解能力”
  • 【机器学习第一期(Python)】梯度提升决策树 GBDT
  • Pycharm无法运行Vue项目的解决办法
  • Java 泛型详解:从入门到实战
  • jdbc实现跨库分页查询demo
  • 人力资源管理系统
  • Spring Cloud Config动态刷新实战指南
  • 用户统计-01.需求分析和设计
  • GNSS位移监测站在大坝安全中的用处
  • 渗透实战:使用隐式转换覆盖toString的反射型xss
  • Day43 复习日 图像数据集——CNN
  • 【PX4-AutoPilot教程-TIPS】PX4系统命令行控制台ConsolesShells常用命令(持续更新)
  • ES文件管理器v4.4.3(ES文件浏览器)
  • 鸿蒙 FoldSplitContainer 解析:折叠屏布局适配与状态管理
  • MySQL之存储函数与触发器详解
  • 多相机人脸扫描设备如何助力高效打造数字教育孪生体?
  • ethers.js express vue2 定时任务每天凌晨2点监听合约地址数据同步到Mysql整理