快照读和当前读
在 MySQL 的 InnoDB 存储引擎中,快照读(Snapshot Read)和当前读(Current Read)是两种不同的读取方式,它们在处理并发事务时有不同的行为和应用场景。
快照读(Snapshot Read)
快照读是一种一致性非锁定读,它通过多版本并发控制(MVCC)机制来实现。这意味着即使在读取数据时有其他事务正在修改数据,快照读也会返回一个一致性的视图,不会被其他事务的更改所影响。
特点
- 无锁读取:不会加锁,允许并发读取。
- 一致性视图:读取的数据是事务开始时刻的数据快照,即使其他事务正在对数据进行修改。
- 避免锁冲突:适合高并发的读操作,减少锁争用。
应用场景
- 高并发读操作:需要读取大量数据且希望避免锁争用的场景。
- 事务中的读操作:读取数据时希望看到一致性的视图,而不是最新的数据。
示例
事务 A 和事务 B 并发进行:
1 |
|
事务 A 的 SELECT 语句是快照读,它读取的是事务开始时的视图,不受事务 B 的 UPDATE 操作影响。
即使有其他事务在修改 employees
表中的数据,上述查询仍然会返回事务开始时的视图。
当前读(Current Read)
当前读是一种锁定读,它会读取最新的数据,并且在读取数据时会对读取的数据加锁,以确保数据的独占访问。
特点
- 锁定读取:读取的数据会加锁,以确保其他事务不能同时修改这些数据。
- 读取最新数据:读取的数据是最新的数据,而不是事务开始时的数据快照。
- 防止幻读:适用于需要确保数据一致性和完整性的场景。
应用场景
- 更新操作:需要读取最新数据并对其进行更新的场景。
- 防止并发修改:需要确保数据在读取和更新之间不会被其他事务修改的场景。
示例
以下操作是当前读:
1 |
|
事务 A 和事务 B 并发进行:
1 |
|
事务 A 的 SELECT … FOR UPDATE 是当前读,它会对读取的数据加锁,阻止事务 B 在事务 A 提交之前对相同数据进行更新。
上述查询会加锁,以确保其他事务在当前事务完成之前不能修改或插入相关的数据。
对比
读方式 | 特点 | 应用场景 | 示例 |
---|---|---|---|
快照读 | 无锁读取,一致性视图 | 高并发读操作,事务中的读操作 | SELECT * FROM employees WHERE dept_id = 1; |
当前读 | 锁定读取,读取最新数据,防止幻读 | 更新操作,防止并发修改 | SELECT * FROM employees WHERE dept_id = 1 FOR UPDATE; |
总结
- 快照读:通过 MVCC 提供一致性视图,不加锁,适合高并发读操作。
- 当前读:通过加锁确保读取最新数据,适合需要防止并发修改的更新操作。
根据具体的应用场景和需求选择合适的读取方式,可以平衡系统的并发性能和数据一致性。
快照读和当前读
https://randzz.cn/b4a6fe94d4b1/快照读和当前读/