`UPDATE SET WHERE` 是否存在并发问题?

Does `UPDATE SET WHERE` have concurrency issues?

考虑下面的陈述

UPDATE SET is_locked = 1 WHERE id = 1 and is_locked = 0;

是否存在并发更新下的一致性问题?为什么?

(MySQL 5.7,事务隔离级别为 REPEATABLE-READ)

不,它不需要,因为更新需要对正在更新的记录的独占锁,而 innodb 不会一次授予超过 1 个对记录的独占锁。

(解决一些评论)

在许多(不是所有)情况下,这是要遵循的模式:

BEGIN;
SELECT ... FOR UPDATE;
use the data from the SELECT to make decisions, then
UPDATE the row(s) selected
COMMIT.

如果您离开 FOR UPDATE,那么其他一些连接可能会潜入并更改行,只会让您的 UPDATE 破坏这些更改。 (当然也有这样的情况"OK"。)

至于

UPDATE tbl SET is_locked = 1 WHERE id = 1 and is_locked = 0;

没有问题。那句话,不管你怎么运行它,都是"atomic"。没有其他连接可以潜入并扰乱你。 (不过逻辑上是幂等的,所以不是问题。)

"regardless"我指的是autocommitBEGINtx_isolation_mode