剖析 MySQL InnoDB 共享行锁 (S) & 排他行锁 (X)

MySQL InnoDB 共享行锁(S) & 排他行锁(X)

注意:行锁只在 InnoDB 引擎,并且事务开启下生效;自动提交 autocommit=1 时锁会立刻释放,看不到锁效果 。

行锁是记录锁,锁住某一行数据,不是锁整张表。

1、共享行锁 S(Shared,读锁)

加锁语法 :select ... for share;(MySQL8.0,旧版 LOCK IN SHARE MODE)

  • 特性:
  1. 多个事务可以同时加S锁(读读兼容)
  2. 如果事务A对一行加S锁,其他事务还可以继续加S锁 ,但不能加X排他锁
  3. S锁事务可以读数据;不能修改这行数据,要修改必须升级为X锁

使用场景

  1. 先读取数据,后续业务要修改,希望防止别人把这条数据删掉/做重大修改,但允许别人读取

举例:订单校验,先查询订单状态,后续要更新订单;不希望别的事务直接更新/删除这条订单,但允许其他业务读取订单信息。

sql 复制代码
begin;
select * from t_order where id=100 for share; -- 加S共享行锁
-- 业务逻辑校验
update t_order set status=2 where id=100; -- 尝试修改,S锁升级X锁,如果此时有其他S锁,会阻塞等待
commit;
  1. 多事务共同读取同一行,数据要保证读取期间不被别的事务改写

适合:数据核对、统计,允许多方读,但禁止别人写。

⚠️ S锁坑点:

如果多个事务同时加S锁,然后都想更新这行,互相等待,直接死锁 。

事务1:S锁 → 想升级X锁;事务2:S锁 → 想升级X锁;互相阻塞,死锁。

所以业务要更新的场景,更推荐直接用X锁,不要用S锁。

2、排他行锁 X(Exclusive,写锁)

加锁语法 :select ... for update;

DML语句(update / delete / insert)会自动给命中行加X排他锁。

  • 特性:
  1. 互斥 :一行加了X锁之后,其他事务既不能加S锁,也不能加X锁
  2. 持有X锁的事务,可以读写这行;其他事务读写都会阻塞等待锁释放。

使用场景

  1. 并发更新,防止超卖、数据错乱(最常用)

扣库存:查询库存同时上锁,不允许其他事务修改该行,避免并发超卖

sql 复制代码
begin;
select stock from goods where id=1 for update; -- 加X行锁
update goods set stock = stock -1 where id=1;
commit;
  1. 业务确定接下来就要修改/删除该行,直接上写锁,避免幻读、脏写
  2. delete、update 执行时,InnoDB自动加X行锁,不需要手动写for update。

锁兼容矩阵(重点)

当前持有锁 申请S锁 申请X锁
S锁 ✅ 通过 ❌ 阻塞
X锁 ❌ 阻塞 ❌ 阻塞

对比总结

锁类型 语法 核心特点 适用场景 不适合场景
S共享行锁 select ... for share 允许多个事务读;阻止别人写 多读,短时间校验,允许其他事务读取 后续要更新,多并发更新,容易死锁
X排他行锁 select ... for update/update/delete 独占,别人不能读也不能写 并发修改、扣库存、订单状态变更 大量并发只读场景,会造成大量阻塞

实际业务最佳实践

  1. 绝大多数并发更新场景,直接用 X锁(for update),尽量少用S锁,规避S锁带来的死锁风险。
  2. S锁适合:只做校验读取,确定本事务不会修改该行的场景。
  3. 行锁生效前提:where条件命中索引,如果没走索引,InnoDB会退化成表锁,整张表锁住,性能灾难。
  4. 锁直到事务commit / rollback才释放,事务不要写大业务,尽快提交,减少锁持有时间。

补充区分快照读 vs 当前读

  • 普通select:快照读,不加锁,走MVCC,不受行锁影响,可以读到旧版本数据。
  • for share / for update / update / delete:当前读,会真实加行锁。

举个例子:A事务给一行加X锁;B事务普通select依然可以查到数据(MVCC快照),但B执行select ... for update就会阻塞。

相关推荐
小白男神3 天前
MySQL进阶学习四(存储过程、游标、触发器)
mysql
这个DBA有点耶3 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
DBA_G3 天前
从地面到云霄:GBase数据库在民航三大场景的落地实践
数据库
自由能燃气设备3 天前
商用全预混低氮冷凝锅炉免费方案vs付费方案对比+选型避坑指南
大数据·数据库·人工智能
科创致远3 天前
科创致远 ESOP 系统核心效能与实战价值展示
大数据·数据库·人工智能·精益工程
kybs19913 天前
全球灾害数据分析可视化 毕业设计-附源码66794
vue.js·spring boot·mysql·安全·django·c#·asp.net
2601_962218613 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法
程序猿_极客3 天前
【免费】分享一套优质的基于SSM的校园失物招领系统的设计与实现,源码+文档+视频详解(讲解)
java·mysql·ssm·课程设计·失物招领系统
张洛闻Eren3 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
于平安3 天前
MySQL-触发器
数据库·mysql