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

时间:2016-09-23 11:01:01

标签: mysql transactions locking innodb rowlocking

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

更新

第二次FOR UPDATE查询

需要SELECT

1 个答案:

答案 0 :(得分:1)

您看到的行动有效。使用" 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将运行,获取新值。一切都很好。

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