关于RDBMS中Repeatable-Read隔离级及幻读场景的疑惑
可重复读(Repeatable-Read)隔离级运作机制解惑
首先得纠正你一个关键误解:可重复读的快照不是整个数据库的物理副本,它本质是事务启动时的逻辑一致性读视图,核心保证的是当前事务内多次读操作的结果一致,而非完全隔绝其他事务的写入影响——尤其是针对事务从未访问过的行。
针对你给出的场景拆解:
- Tx1和Tx2启动后都执行了
SELECT * FROM TABLE,此时两者的读视图都包含10行数据,这一步符合你对快照的预期。 - Tx1插入ID=11的新行并提交,这个行是在Tx2的读视图生成之后新增的。
- Tx2执行
UPDATE ROW WITH ID=11能成功,原因在于:- 可重复读隔离级的快照规则只作用于SELECT类的读操作,对于UPDATE/DELETE这类写操作,数据库会直接定位到该行的最新版本,先检查是否存在,然后加上行级锁。只要该行已被其他事务提交,写操作就会直接作用于这个最新版本,而非事务快照里的数据。
- 你提到这是幻读,但严格来说这不属于标准幻读场景。幻读指的是同一事务内两次相同的范围查询,第二次返回了第一次没有的新行。而这里Tx2是直接更新了一个不在自己读视图里的行,属于“写操作不受读视图限制”的正常行为——可重复读只保证读的一致性,不阻止写操作访问其他事务提交的新行。
最后再明确两个点:
- 可重复读的“快照”是读视图,不是写视图。读操作看快照,写操作直接对接最新数据。
- 用Git分支类比数据库快照并不准确,Git分支是完整的物理副本,但数据库的快照是逻辑层面的一致性视图,不会复制整个数据库的数据,只是记录了事务启动时各个数据行的版本信息。
内容的提问来源于stack exchange,提问作者Rammohan
相关产品推荐
相关产品推荐

