讲师中心 微信公众号
AI工具推荐 视频效率加速

为什么MySQL只更新一条记录却锁定了多行数据

夜辰小哥_5555

夜辰小哥_5555

发布时间:2026-09-13 06:02:27

|

230人浏览过

|

来源于php中文网

原创

MySQL更新单行却锁多行,是因InnoDB在REPEATABLE READ下默认用Next-Key Lock:非唯一索引等值查询会锁记录及相邻间隙;无索引时全表扫描加锁;隐式类型转换或函数操作导致索引失效也会引发此问题。

为什么mysql只更新一条记录却锁定了多行数据

MySQL只更新一条记录却锁住多行,根本不是语句写错了,而是InnoDB在当前隔离级别和索引条件下,自动把锁“撑开”了——它锁的从来不只是你看到的那一行。

REPEATABLE READ 下 Next-Key Lock 是默认行为

InnoDB 默认隔离级别是 REPEATABLE READ,它用 Next-Key Lock(记录锁 + 间隙锁)来防止幻读。哪怕你写的是 WHERE id = 100 这种精确等值条件,只要 id 不是唯一索引或主键,InnoDB 就可能升级为范围锁。

  • 如果 id 是普通二级索引(非唯一),UPDATE t SET x=1 WHERE id = 100 会锁住该索引项对应的所有主键行 + 相邻间隙
  • 如果表里 id 值是 98、100、102,那么执行 WHERE id = 100 可能实际锁住 (98, 100] 和 (100, 102] 两个临键区间
  • 更隐蔽的是:若 id = 100 根本不存在,InnoDB 仍会加 GAP 锁,比如锁住 (98, 102),阻止其他事务插入 99、101

WHERE 条件没走索引,直接退化为全表扫描

这是最常被忽略的“伪单行更新”陷阱:你以为只改一行,其实 MySQL 正在扫全表加锁。

MySQL
MySQL

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

下载
  • EXPLAIN UPDATE t SET status=1 WHERE user_id = '123' 中 type 显示 ALL,说明没走索引
  • 原因可能是:user_id 是 BIGINT 类型,但传了字符串 '123',触发隐式转换,索引失效
  • 也可能是函数包裹:WHERE DATE(create_time) = '2024-01-01' → 改成 WHERE create_time >= '2024-01-01' AND create_time
  • 一旦全表扫描,InnoDB 会对所有扫描到的行加意向锁,甚至升级为表级锁(尤其在低版本或特殊配置下)

联合索引使用不当导致锁范围扩大

联合索引不是“用了就安全”,顺序和覆盖决定锁粒度。

  • 建了索引 (a, b),但只写 WHERE a = 1:InnoDB 会锁定所有满足 a = 1 的行,并对这些行的 b 值之间加间隙锁
  • 如果再加 ORDER BY b 或 LIMIT 1,优化器可能放弃索引下推,回表后重新排序,锁住更多临时结果
  • 正确做法:确保 WHERE 包含联合索引最左前缀,且尽量让条件能精确命中单个索引条目(如 WHERE a = 1 AND b = 2)

SELECT FOR UPDATE 比 UPDATE 更容易锁多行

很多人用 SELECT ... FOR UPDATE 做前置校验,却没意识到它比直接 UPDATE 更危险。

  • SELECT * FROM t WHERE status = 0 ORDER BY id LIMIT 1 FOR UPDATE:即使只取 1 行,ORDER BY + LIMIT 在 RR 级别下仍可能锁住整个扫描范围内的所有间隙
  • 更糟的是:status = 0 如果没索引,就是全表加锁;即使有索引,也可能因数据分布稀疏而锁住大量无效行
  • 替代方案:改用带主键等值条件的原子 UPDATE,例如 UPDATE t SET status = 1 WHERE id = ? AND status = 0,靠 ROW_COUNT() 判断是否成功

真正难处理的不是“怎么加锁”,而是“为什么我什么都没做错,它还是锁多了”——间隙锁不可见、隐式转换无声无息、联合索引的最左匹配规则又容易误判。线上出问题时,第一反应不该是调参数,而是立刻 EXPLAIN 那条 SQL,再对照 SHOW ENGINE INNODB STATUS 里的锁详情,看清楚到底哪几行、哪种锁被拿住了。

热门AI工具

更多
音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

相关专题

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

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

2413

2023.06.20

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

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

1459

2023.06.21

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

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

855

2023.07.18

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

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

3412

2023.07.19

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

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

5848

2023.07.25

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

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

1259

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

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

6111

2023.08.11

mysql忘记密码
mysql忘记密码

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

5282

2023.08.14

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

热门下载

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

精品课程

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

共1课时 | 193人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn