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,性能最佳
相关推荐
云上漫步者1 分钟前
深度实战:Rust交叉编译适配OpenHarmony PC——unicode_width完整适配案例
开发语言·后端·rust·harmonyos
Java水解25 分钟前
MySQL必备基础
后端·mysql
Java水解26 分钟前
Spring AOP原理深度解析:代理模式、JDK动态代理与CGLIB
后端·spring
无限大639 分钟前
为什么显示器分辨率越高越清晰?——从像素到 4K/8K 的视觉革命
后端
阿苟1 小时前
nginx部署踩坑
前端·后端
ChineHe1 小时前
Gin框架基础篇001_路由与路由组详解
后端·golang·gin
神奇小汤圆1 小时前
深入理解Linux IPIP隧道:原理、配置与实战
后端
计算机毕设VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue酒店管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
laozhoy11 小时前
深入理解Go语言errors.As方法:灵活的错误类型识别
开发语言·后端·golang
周杰伦_Jay1 小时前
【Go 语言】核心特性、基础语法及面试题
开发语言·后端·golang