当前位置: 首页 > news >正文

MYSQL 事务原理

脏读:一个事务读到了另一个事务尚未提交的修改。

连接1:

连接2:

连接1事务未提交,但是连接2可以读到其修改。

将隔离级别设置为:read commited (读已提交) 可以解决脏读。

不可重复读:同一事务里,两次读同一行,结果不一样。原因是中间有别的事务提交了。

将隔离级别设置为:repeatable read (可重复读) 可以解决不可重复读。

幻读:同一事务里,两次读取同一个范围内的记录得到的结果集不同。当前读和快照读不一样。

在repeatable级别通过加锁解决幻读问题

连接1

连接2:

连接2若想插入,会阻塞等待。当连接1 commit或rollback才会执行。

read uncommited : 脏读、不可重复读、幻读。

read commited : 不可重复读、幻读。

repeatable read : 幻读。

MVCC 是什么

MVCC = Multi-Version Concurrency Control(多版本并发控制)

核心想法:一行数据不只留 当前值,还会保留历史版本。读的时候尽量读某个历史版本,写的时候生成新版本,这样读写常常不用互相锁死。

可以把它想成一行记录有一条 "版本链":

当前版本 (trx=100, balance=300)
↑ undo
旧版本 (trx=80, balance=200)
↑ undo
更旧版本 (trx=50, balance=100)

更新时:写出新版本,旧值放到 undo log,串成链

普通SELECT(快照读):沿版本链往回找,找到「自己可见」的那个版本

SELECT ... FOR UPDATE(当前读):读最新已提交/需要加锁的版本,走锁,不完全靠这套纯快照逻辑。

Read View 是什么

Read View(读视图) 是事务做一致性读时,InnoDB 生成的一份「可见性规则快照」。

它回答的问题只有一个:版本链上这个版本,当前事务能不能看见?

判断逻辑直观理解:

  1. 版本由已提交且在我视野之前的事务产生 → 可见
  2. 版本由我自己产生 → 可见
  3. 版本由生成 Read View 时还未提交的事务产生 → 不可见(继续沿 undo 找更老版本)
  4. 版本由比我视野更晚的事务产生 → 不可见

找到第一个可见版本,就是这次SELECT的结果。

READ COMMITTED

  • 每次普通SELECT新建一个 Read View
  • 所以中间别人COMMIT了,下一次查可能看到新值
  • 可能不可重复读、幻读

REPEATABLE READ

  • 事务里第一次普通SELECT创建 Read View,之后复用
  • 所以同一事务里多次普通查询,视野不变
  • 可重复读;普通SELECT也很难看到新插入的「幻行」

隔离级别差异:很大程度上就是 Read View 创建时机不同(每次读新建 vs 事务内复用)

在 InnoDB 里,读分两种:

快照读(一致性读)

读的是 Read View 下可见的历史版本,一般不加锁(或几乎不挡别人写)。

常见语句:

SELECT * FROM accounts WHERE id = 1;

特点:

  • 走 MVCC + Read View
  • RR 下同一事务多次读,结果通常一致
  • 可能不是磁盘上「此刻最新已提交」的那一版

当前读

读的是 最新版本,并且会加锁,保证读到的行别人不能随便改。

常见语句:

SELECT ... FOR UPDATE; SELECT ... LOCK IN SHARE MODE; -- 或 FOR SHARE UPDATE / DELETE; -- 先当前读再改 INSERT ... SELECT ...; -- 其中的 SELECT 也可能是当前读

特点:

  • 不靠「复用旧 Read View」来读旧版本
  • 要加行锁 / 间隙锁等
  • 能读到最新已提交数据(并锁住,防止并发冲突)

MySQL 锁机制详解

MySQL 锁
├── 表级锁:表锁、意向锁、MDL
└── 行级锁(InnoDB 主力)
├── 模式:共享锁 S / 排他锁 X
└── 范围:记录锁 Record / 间隙锁 Gap / 临键锁 Next-Key

行锁的两种模式:S 和 X

含义常见语句

共享锁 S

允许别人再加 S,不允许加 X

SELECT ... FOR SHARE

排他锁 X

不允许别人再加 S/X

SELECT ... FOR UPDATEUPDATEDELETE

兼容关系很简单:

  • S 与 S:兼容
  • S 与 X:不兼容
  • X 与 X:不兼容

所以:

  • A 持有某行 X 锁时,B 再对同行FOR UPDATE→ B 等待
  • A 只是普通SELECT(快照读)→ 通常不持有行锁,B 的更新不一定被它堵住

行锁的三种范围:Record / Gap / Next-Key

这是 InnoDB 锁最核心的部分。

1. 记录锁(Record Lock)

锁住已经存在的索引记录。

SELECT * FROM accounts WHERE id = 1 FOR UPDATE;

效果:锁住id=1这一行,防止别人改/删它。

2. 间隙锁(Gap Lock)

锁住索引记录之间的空隙,不锁某行本身,但阻止别人往空隙里插入。

例如索引上有id = 10, 20,间隙(10, 20)被锁后:

INSERT INTO t VALUES (15, ...); -- 可能被堵住

间隙锁的主要意义:防止幻读(当前读场景下,别插进新行)。

3. 临键锁(Next-Key Lock)

Next-Key Lock = Record Lock + Gap Lock

InnoDB 在 REPEATABLE READ 下,当前读默认常用这套算法:
锁住一个左开右闭区间,例如(10, 20]

既防止改20,也防止在1020之间插入新记录。

快照读 vs 当前读

这是理解「锁」和「MVCC」分工的关键。

快照读

SELECT * FROM accounts WHERE id = 1;
  • 读的是 Read View 下可见的历史版本
  • 一般不加行锁
  • RR 下同一事务多次普通查询,结果通常稳定

当前读

SELECT * FROM accounts WHERE id = 1 FOR UPDATE; UPDATE accounts SET balance = 200 WHERE id = 1; DELETE FROM accounts WHERE id = 1;
  • 读最新数据
  • 加锁
  • 可能阻塞其他事务的冲突写/插

隔离级别如何影响锁

隔离级别简要特征

READ UNCOMMITTED

可脏读,基本不用于生产

READ COMMITTED

每次普通 SELECT 新 Read View;当前读主要是记录锁,间隙锁很少

REPEATABLE READ(默认)

快照复用;当前读大量使用 Next-Key,防幻读更强

SERIALIZABLE

普通 SELECT 也会趋向加锁读,并发最差、最严格

  • 大多数业务用默认 RR 就够
  • 若热点行冲突严重、且能接受不可重复读,可评估 RC
  • 不要为了“更安全”一上来就 SERIALIZABLE
http://www.cnnetsun.cn/news/3923641.html

相关文章:

  • Plotly交互式数据可视化实战指南
  • 拒绝盲目开工!深度解析网站建设进度安排中的关键节点与避坑指南,助您高效落地
  • AI代码生成从功能实现到工程质量的提升策略与实践
  • 重新注册VS商标设计注册驳回复审要花多少钱?
  • 《我的世界》服务器生存开局指南:高效逃离出生点与选址建家
  • AI Agent长任务运行时架构:状态持久化、Judge闭环与自主续航解析
  • MySQL硬扛百万向量搜索:LSH索引实战与RAG技术选型思考
  • 鸿蒙 测试工具:DevEco Testing(一)
  • MiniMax H3 深度拆解:全模态视频模型来了,AI 漫剧系统该如何重构?
  • 构建高效人生系统:从时间管理到能量优化
  • 软件开发全套文档、必要性、结构性思考
  • 采购部引入AI Agent后,4个场景的效率提升一览:企业智能自动化的全链路拆解
  • RAG内存瓶颈破解:用Rust库turbovec实现向量索引8倍内存压缩
  • 工业智造背后的隐形冠军:CNC强力磁盘如何提升加工精度与东莞网站建设中的细节打磨哲学
  • SpringBoot汉服租赁系统开发与优化实践
  • Bilibili-Evolved:如何用模块化脚本技术重构B站用户体验
  • 小程序转app ios Android 视频播放
  • 水果蔬菜分类图像分类 智慧化农业蔬菜水果分类数据集 果蔬分类数据集的应用 智慧农业数据集 生鲜识别 超市自动结算 AI营养分析 移动端果蔬识别APP
  • 探究东莞网站建设哪家专业,揭秘行业背后不为人知的真相与价值
  • JMeter脚本优化实战:从入门到精通,打造高性能压测方案
  • 从Jeff Dean工程遗产看分布式系统演进与开发者深度能力构建
  • 广告账户的「体检报告」:ROAS不是唯一指标,这4个数据才是真正的预警信号
  • 电信用户流失预测:机器学习实战与特征工程解析
  • 南阳网站建设8iwang深度解析:如何让本地中小企业的线上大门更加宽敞明亮
  • 2026版Android Studio安装与配置全指南
  • 跨平台GPU开发实战:CUDA环境搭建与Mac远程开发指南
  • Unity开发必知:API兼容级别、C#版本与项目稳定的三角关系
  • 设计带操作界面的应用程序
  • 揭秘建设银行江西分行官方网站的便捷服务与数字化转型之路,打造百姓身边的贴心金融管家
  • Redisson MultiLock 原理