MySQL数据库基本概念中什么是锁机制?行锁、表锁与死锁预防策略

老涛酱_4087

老涛酱_4087

2026-03-20

555人浏览

原创

锁机制本质是并发控制的“交通规则”,用于保障事务隔离级别,防止脏读、不可重复读和幻读;其类型与范围取决于索引命中情况、隔离级别及where条件。

mysql数据库基本概念中什么是锁机制?行锁、表锁与死锁预防策略

锁机制本质是啥?不是功能,是并发控制的“交通规则”

MySQL 锁机制不是可选插件,而是事务隔离级别的底层执行保障。它解决的核心问题只有一个:当多个事务同时读写同一份数据时,如何避免脏读、不可重复读、幻读——说白了,就是不让数据“变魔术”。InnoDB 默认用行锁,但实际加什么锁、锁多大范围,完全取决于查询是否命中索引、隔离级别(RR 还是 RC)、甚至 WHERE 条件里有没有范围(比如 BETWEEN 或 LIKE 'a%')。没索引?哪怕只改一行,也可能触发全表扫描+全表行锁,看起来像锁表。

行锁 vs 表锁:别光看粒度,要看“谁在真正执行”

行锁不是万能并发解药,表锁也不是性能毒药——关键看场景和实现方式:

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
  • SELECT ... FOR UPDATE 和 SELECT ... LOCK IN SHARE MODE 触发的是行锁(前提是 WHERE 走索引),但若索引失效,InnoDB 会退化为对所有扫描行加锁,10 万行就加 10 万把锁,CPU 和内存压力陡增
  • LOCK TABLES t1 WRITE 是显式表锁,简单粗暴,适用于批量导入、DDL 前置保护等短时独占操作;但它会阻塞所有其他线程对这张表的任何读写,包括 SELECT
  • InnoDB 默认不升级行锁为表锁,但“逻辑上锁全表”很常见:比如在 RR 隔离级别下执行 SELECT * FROM users WHERE status = 0 FOR UPDATE,而 status 列无索引 → 全表扫描 → 每行都加 X 锁 → 效果≈表锁,但开销比真表锁大得多

死锁不是偶发事故,是加锁顺序错位的必然结果

InnoDB 能自动检测死锁并回滚其中一个事务(报错 ERROR 1213 (40001): Deadlock found when trying to get lock),但这只是止损,不是根治。真正要防,得从代码层干预:

  • 所有涉及多行更新的业务(比如分账、库存扣减),必须统一按主键或唯一索引升序加锁:SELECT * FROM orders WHERE id IN (15, 7, 22) FOR UPDATE → MySQL 内部会自动按 7, 15, 22 排序加锁;但如果写成两条语句分别锁 id=15 和 id=7,就极易和另一事务形成循环等待
  • 避免在事务中混合使用快照读(普通 SELECT)和锁定读(FOR UPDATE),尤其在 RR 级别下,前者不加锁,后者可能触发 gap lock,边界模糊易冲突
  • 关键业务开启 innodb_print_all_deadlocks = ON,让死锁详情进 error log;配合 SHOW ENGINE INNODB STATUS\G 查最近一次死锁链,重点看 “WAITING FOR THIS LOCK TO BE GRANTED” 和 “HOLDS THE LOCK(S)” 两段,直接定位哪两行、哪两个事务卡住了

最容易被忽略的坑:间隙锁(gap lock)根本不在你查的那行上

你以为锁的是数据行?在 RR 隔离级别下,InnoDB 默认用 next-key lock(行锁 + 前面的间隙锁)。比如 id 索引值是 1, 5, 10,执行 SELECT * FROM t WHERE id > 3 AND id ,实际锁住的是 (1,5)、(5,10) 两个间隙,以及记录 <code>5 —— 意味着其他事务无法插入 id=2、id=4、id=6 等任何落在这些区间的值。这个行为在唯一索引的等值查询(如 WHERE id = 5)中会退化为纯 record lock,但只要条件含范围、或用的是非唯一索引,gap lock 就如影随形。线上调优时,宁可降级到 RC 隔离级别砍掉 gap lock,也别硬扛它带来的隐式锁膨胀。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

2173

6

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.21

1339

5

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

775

5

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.19

2972

5

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.25

4968

4

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.08

1119

3

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.11

5251

4

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

2023.08.14

4622

7

mysql事务隔离级别
mysql事务隔离级别

mysql规范中定义了四种事务隔离级别,不同的隔离级别对事务的处理有所不同。本专题为大家提供mysql事务隔离级别相关的文章内容,大家可以免费体验。

2023.08.16

6094

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 183人学习