剖析 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就会阻塞。

相关推荐
小天源17 分钟前
智叟云集系统 · 架构与职责分层
服务器·前端·数据库
herinspace1 小时前
管家婆实用贴-SQL 2008如何修改成混合模式
服务器·数据库·sql·管家婆软件·财务软件·合肥管家婆软件
打螺丝的小李1 小时前
制造企业质量管理系统的三类产品形态:分别解决什么问题
数据库·制造
xixingzhe21 小时前
MySQL 锁表故障排查与处理
数据库·mysql
真上帝的左手2 小时前
30. 技术专题-‌应用框架组件-关系型数据库-MySQL-Mybatis
数据库·分布式·mysql·中间件·mybatis
为思念酝酿的痛2 小时前
MySQL表的连接
数据库·mysql
数字新视界2 小时前
机房动环监控系统在提升数据中心能效与安全中的应用探索
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
bksczm3 小时前
MySQL之存储引擎
数据库·mysql
计算机毕设定制辅导-无忧学长3 小时前
《基于微信小程序健康习惯激励系统设计与实现》
java·spring boot·mysql·微信小程序·uniapp·健康习惯激励系统
大模型最新论文速读3 小时前
text-to-sql:从学术玩具到生产落地
数据库·sql