同一个事务、同一张快照,为什么读到的值变了
RR 下,事务 B 的快照里 k = 1。之后 C 提交,把 k 改成 2。
-- B
SELECT k FROM t WHERE id = 1; -- 1,读快照
UPDATE t SET k = k + 1 WHERE id = 1;
SELECT k FROM t WHERE id = 1; -- 3,不是 2快照没变,变的是这一行多了一个新版本:
- UPDATE 是当前读:它读最新已提交的值 2,而不是快照里的 1。否则就会把 C 的修改盖掉(丢失更新)。
- 2 + 1 = 3,这个新版本是 B 自己写的。可见性规则里,自己改的永远可见,所以后面的普通 SELECT 读到 3。
两个推论,都实测过:
- 只有真被 B 改到的行会这样。没改到的其他行,照样读快照里的旧值。
- UPDATE 如果什么都没改(新值和旧值相同),InnoDB 不写新版本,后面读到的仍是快照。