当前位置: 代码网 > it编程>数据库>Mysql > mysql中快照读和当前读操作方法

mysql中快照读和当前读操作方法

2026年04月07日 Mysql 我要评论
前言在 mysql innodb 存储引擎中,快照读(snapshot read) 和 当前读(current read) 是两种核心的读操作模式,二者的设计目标、实现方式、加锁行为和适用场景截然不同

前言

在 mysql innodb 存储引擎中,快照读(snapshot read) 和 当前读(current read) 是两种核心的读操作模式,二者的设计目标、实现方式、加锁行为和适用场景截然不同,其中快照读是 mvcc 机制的核心体现,当前读则依赖锁机制保证数据一致性。

一、快照读(snapshot read)

  1. 定义
    快照读是指读取数据的历史版本(快照),而非数据的最新版本,是 innodb 实现 mvcc 多版本并发控制的核心读方式。
  2. 核心特征
  • 无锁读取:读取时不加任何行锁 / 表锁,完全避免锁竞争,读写互不阻塞(读不阻塞写,写不阻塞读);
  • 依赖 mvcc:通过「行版本链 + read view」判断数据可见性,只读取符合当前事务隔离级别的历史版本;
  • 版本一致性:在不同隔离级别下,快照读的版本可见性规则不同(如可重复读级别下,事务内多次快照读复用同一个 read view,保证结果一致)。
  1. 适用场景
    所有普通的 select 语句(无特殊锁提示)都属于快照读,例如:
select * from user where id = 1;
select name from user where age > 20;
  1. 典型行为(以可重复读为例)
    假设事务 a 执行快照读读取 id=1 的数据(值为 tom),此时事务 b 修改该数据为 jerry 并提交,但事务 a 后续的快照读仍会读取到 tom(因为复用第一次生成的 read view,看不到事务 b 提交的新版本)。

二、当前读(current read)

  1. 定义
    当前读是指读取数据的最新版本,且读取时会对目标数据加锁(行锁 / 间隙锁),防止其他事务修改该数据,保证读取和后续操作的原子性。
  2. 核心特征
  • 加锁读取:读取最新版本的同时,会为数据加锁(排他锁 / 共享锁),阻塞其他事务的写操作或当前读操作;
  • 不依赖 mvcc:直接读取最新版本,无视版本链和 read view;
  • 强一致性:保证读取到的是数据的最新状态,适用于需要精准操作最新数据的场景。
  1. 适用场景
    以下操作均属于当前读:
操作类型示例加锁类型
加锁的selectselect * from user where id = 1 for update;排他锁(x 锁),阻塞其他写操作和 for update 操作
加锁的 selectselect * from user where id = 1 lock in share mode;共享锁(s 锁),阻塞其他排他锁操作,允许共享锁操作
写操作(隐式当前读)insert into user (name) values (‘tom’);排他锁(插入行加锁)
写操作(隐式当前读)update user set name = ‘jerry’ where id = 1;先对目标行加排他锁,再读取最新版本并修改
写操作(隐式当前读)delete from user where id = 1;先对目标行加排他锁,再读取最新版本并标记删除
  1. 典型行为
    假设事务 a 执行 select * from user where id = 1 for update;(当前读),此时会读取 id=1 的最新版本并加排他锁:
  • 事务 b 若执行 update user set name = ‘jack’ where id = 1;,会被阻塞,直到事务 a 提交 / 回滚;
  • 事务 b 若执行普通 select(快照读),仍可读取到历史版本(不受当前读锁的影响)。

三、快照读 vs 当前读 核心对比

维度快照读当前读
读取数据版本历史版本(快照)最新版本
加锁行为无锁加行锁 / 间隙锁(排他 / 共享)
依赖机制 mvcc(版本链 + read view)锁机制(行锁、next-key lock)
并发特性读写不阻塞,性能高读阻塞写(排他锁),写阻塞读,性能较低
隔离性保证可重复读 / 读已提交(依赖隔离级别)串行化级别的强一致性
适用场景普通查询,追求并发性能精准操作最新数据(如更新 / 删除前校验、加锁查询)
典型语句select …(无锁提示) select … for update/insert/update/delete

四、关键补充说明

  1. 隔离级别的影响:
  • 读未提交(read uncommitted):无快照读,直接读取最新版本(等价于当前读),会出现脏读;
  • 串行化(serializable):快照读被降级为当前读(加锁),所有读操作都加锁,完全串行执行。
  1. 写操作的隐式当前读:
  • insert/update/delete 执行时,会先触发「当前读」读取最新版本的数据,再执行写操作,确保修改的是最新数据,避免丢失更新。
  1. 锁的范围:
  • 当前读的加锁范围不仅包含匹配的行,还可能包含间隙(next-key lock),防止幻读(可重复读级别下)。

总结

  • 快照读是 innodb 高并发的核心,通过 mvcc 实现无锁读,牺牲 “最新性” 换取性能;
  • 当前读是保证数据强一致性的手段,通过加锁读取最新版本,牺牲 “并发性” 换取准确性;
  • 日常开发中,普通查询用快照读即可,需要精准操作最新数据(如秒杀、库存扣减)时,需用当前读(如 select … for update)。
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com