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

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

MySql = v5.6

Table引擎=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还是做错了什么?

更新:

需要FOR UPDATE2号SELECT查询

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

第一个连接获取了一种阻止 写入 但不是 读取 的锁。如果第二个连接完成了 FOR UPDATEINSERT 或其他 "write" 类型的操作,它要么被延迟等待锁被释放,要么死锁。 (死锁也需要其他锁。)

常用模式

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

如果两个线程 运行 在同一行的 "same" 时间执行该代码,则第二个线程将在 SELECT..FOR UPDATE 停止。第一个线程完成后,SELECT 将 运行 获取新值。一切顺利。

与此同时,其他线程可以SELECT(无需更新)并获得一些价值。将这些线程视为在事务之前或之后获取值,具体取决于所有线程的确切时间。重要的是这些 'other' 线程将看到一个 一致的 数据视图——或者 none已应用该事务中的更新,或已应用 all。这就是"Atomic"的意思。