繁体   English   中英

FOR UPDATE 似乎没有锁定 MySql InnoDB 中的行

[英]FOR UPDATE doesn't seem to lock the row in MySql InnoDB

MySql = v5.6

表引擎 = InnoDB

我打开了一个 mysql cli。 我跑:

START TRANSACTION;

SELECT id FROM my_table WHERE id=1 FOR UPDATE;

然后我打开第二个 cli 并运行:

SELECT id FROM my_table WHERE id=1;

我预计它会等到我提交或回滚第一个事务,但它没有,它只是立即带回行,就好像没有发生行锁定一样。

我做了另一个测试,我在第一个 cli 中更新了一个status字段,在我提交事务之前我看不到第二个 cli 中的变化,证明事务确实在工作。

我是否误解了FOR UPDATE或做错了什么?

更新:

在第二个SELECT查询中需要FOR UPDATE

你看到的那个动作是有效的。 使用“MVCC”,不同的连接可以在行上看到不同的版本。

第一个连接获取了一种可以防止写入但不能防止读取的锁。 如果第二个连接执行了FOR UPDATEINSERT或其他“写入”类型的操作,那么它要么延迟等待释放锁,要么死锁。 (死锁也需要其他锁。)

常见模式

BEGIN;
SELECT ... FOR UPDATE; -- the row(s) you will update in this transaction
miscellany work
UPDATE...;  -- those row(s).
COMMIT;

如果两个线程在“相同”时间在同一行上运行该代码,则第二个SELECT..FOR UPDATE将在SELECT..FOR UPDATE处停止。 第一个线程完成后, SELECT将运行,获取新值。 一切都很好。

同时,其他线程可以SELECT (不用于更新)并获得一些值。 将这些线程视为在事务之前或之后获取值,具体取决于所有线程的确切时间。 重要的是,这些“其他”线程将看到一致的数据视图——要么没有应用该事务中的任何更新,要么已应用所有更新。 这就是“原子”的意思。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM