MySQL

FOR UPDATE 读到了新值,下一条 SELECT 却又读回旧值

RR 下,B 的快照里 k = 1,之后 C 提交把 k 改成 5:

sql
-- B
SELECT k FROM t WHERE id = 1 FOR UPDATE;   -- 5
SELECT k FROM t WHERE id = 1;              -- 1

FOR UPDATE / FOR SHARE 是当前读:读最新已提交的版本并加锁。但它们不产生新版本,快照也不会刷新,所以紧跟着的普通 SELECT 照旧按快照读到 1。

加锁只是挡住别人再改,不改变可见性。想在事务里一直拿最新值,后续读也要加 FOR UPDATE。

两种锁定读的区别:

别人 FOR SHARE别人 FOR UPDATE / 改行别人普通 SELECT
我 FOR SHARE可以要等可以
我 FOR UPDATE要等要等可以
esc