为什么锁定读忽略了隔离级别?

3

示例:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT * FROM t1; // to "create shapshot". For simplicity t1 contains 1 row 1 column which contains value 1.
// another transaction updates this row and change 1 to 2 and commits.
SELECT * FROM t1; // we see no changes. As expected in repeatable read.
SELECT * FROM t1 FOR UPDATE; // i see change row. Why?

我找不到解释这种行为的原因。为什么读锁会忽略隔离级别?


1
请注意,在 FOR UPDATE 后添加 SELECT * FROM t1; 仍然返回值 1。我可以理解为什么会这样,但有点令人惊讶。 - ysth
这是我的期望行为。 - Yevhen Grushko
1个回答

1

https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html中提到:

SELECT ... FOR UPDATE

对于搜索到的索引记录,锁定行和任何相关的索引条目,就像您为这些行发出一个UPDATE语句一样。其他事务被阻止更新这些行,执行SELECT ... FOR SHARE或在某些事务隔离级别下读取数据。一致的读取会忽略在读取视图中存在的记录上设置的所有锁定。(旧版本的记录不能被锁定;它们是通过在内存副本上应用撤销日志来重建的。)

换句话说,锁定读取只能锁定最近提交的一行版本。


1
锁定最近的版本,是的。从该最新版本返回数据听起来像是个惊喜。https://mariadb.com/kb/en/set-transaction/#repeatable-read 更明确地说明可重复读仅适用于非锁定语句。 - ysth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接