MySQL事务隔离级别及S与X锁

1. 假定某商品库存为10,数据库使用mysql的默认隔离级别,请问扣减一个库存同时,有一个查询,查询到的数据库存是多少?

🧠 分析过程

MySQL 默认隔离级别:REPEATABLE READ

MySQL InnoDB 的默认隔离级别是 可重复读(REPEATABLE READ) ,其核心特征:

  • 通过 MVCC(多版本并发控制) 实现;
  • 一个事务中多次读取同一行数据,结果一致(除非自己修改);
  • 未提交事务中修改的数据 ,其他事务看不到
  • 避免了脏读

🧾 举例分析

时间顺序 操作 说明
t1 事务A开始 扣减库存事务开始
t2 事务A执行 UPDATE product SET stock = stock - 1 WHERE id = 1; 将库存改为 9,但未提交
t3 事务B执行 SELECT stock FROM product WHERE id = 1; 查询库存
t4 事务A提交 扣减完成

🔍 t3 时刻:事务B 查询到的结果

因为 MySQL 在 REPEATABLE READ 隔离级别下,

事务B 看不到事务A未提交的修改(MVCC 保证),

所以:

✅ 事务B 查询到的库存 = 10

即使事务A已经执行了 UPDATE,但未提交,其他事务看到的仍是旧版本。

✅ 总结结论

项目 说明
数据库隔离级别 REPEATABLE READ(默认)
库存初始值 10
事务A操作 UPDATE stock = 9(未提交)
事务B操作 SELECT stock
查询结果 10
原因 MVCC 保证读到的是已提交版本,避免脏读

💡 补充:如果换隔离级别会怎样

隔离级别 查询结果 原因
READ UNCOMMITTED 9 能读到未提交数据(脏读)
READ COMMITTED 10 只能读到已提交数据
REPEATABLE READ(默认) 10 使用快照读,读到的是事务开始时的版本
SERIALIZABLE 10 加锁读,阻塞直到事务A提交或回滚

2.数据库s锁与x锁

🧩 一、S锁与X锁的基本定义

锁类型 全称 英文名称 作用
S锁 共享锁 Shared Lock 允许多个事务同时读取同一行,但不允许修改
X锁 排他锁 Exclusive Lock 只允许一个事务对该行进行读写,其他事务不能再加任何锁

🧠 二、加锁后的行为差异

操作类型 需要的锁类型 是否允许并发
SELECT ... LOCK IN SHARE MODE S锁 ✅ 允许其他事务也加S锁(共享读) ❌ 不允许X锁(写)
SELECT ... FOR UPDATE X锁 ❌ 其他事务不能加任何锁(读写都阻塞)
UPDATE / DELETE / INSERT X锁 ❌ 独占该行
普通 SELECT(无锁读) 不加锁(MVCC快照读) ✅ 完全并发,读不阻塞写

🔐 三、S锁与X锁的兼容性矩阵

当前锁类型 申请锁类型 是否兼容
S锁 S锁 ✅(可以同时读取)
S锁 X锁 ❌(阻塞)
X锁 S锁 ❌(阻塞)
X锁 X锁 ❌(阻塞)

👉 结论:

  • 多个 S锁 可以共存。
  • X锁 只能独占。

📊 五、总结对比表

项目 S锁(共享锁) X锁(排他锁)
允许读 ✅(自己可以)
允许写 ✅(自己可以)
可共存 ✅ 多个S锁可共存 ❌ 独占
与MVCC关系 显式加锁读 显式写操作
常见SQL SELECT ... LOCK IN SHARE MODE UPDATEDELETESELECT ... FOR UPDATE

💡 六、实际应用场景

场景 推荐锁类型 原因
需要读取后再判断是否更新 SELECT ... FOR UPDATE 确保数据不会被其他事务修改(加X锁)
仅需读取但希望防止被删除或修改 SELECT ... LOCK IN SHARE MODE 加S锁防止数据被改动
只想查(读一致性) 普通 SELECT 使用MVCC,性能最佳
相关推荐
ServBay3 小时前
打通 AI 编程本地运维边界,利用 MCP 协议简化环境与服务管理
后端·ai编程·mcp
程序员cxuan3 小时前
DeepSeek 杀入多模态,识图功能正式上线!
人工智能·后端·程序员
IT_陈寒6 小时前
SpringBoot这个自动配置坑我跳了三次
前端·人工智能·后端
用户395240998806 小时前
排坑日记:ASP.NET Core 中 "Required field is not provided" 验证错误全记录
后端
用户8356290780517 小时前
使用 Python 自动化 PowerPoint 形状布局与格式设置
后端·python
Oneslide8 小时前
sudo免密权限配置不生效
后端
站大爷IP8 小时前
为什么Python不用var或let声明变量?
后端
赴星半途8 小时前
NestJS实战-创建AuthService
后端
北冥有鱼8 小时前
mqtt 测试
前端·后端