【发布时间】:2017-12-24 10:29:05
【问题描述】:
考虑下面的陈述
UPDATE SET is_locked = 1 WHERE id = 1 and is_locked = 0;
并发更新下是否存在一致性问题?为什么?
(MySQL 5.7,事务隔离级别为REPEATABLE-READ)
【问题讨论】:
标签: mysql concurrency innodb
考虑下面的陈述
UPDATE SET is_locked = 1 WHERE id = 1 and is_locked = 0;
并发更新下是否存在一致性问题?为什么?
(MySQL 5.7,事务隔离级别为REPEATABLE-READ)
【问题讨论】:
标签: mysql concurrency innodb
不,它不需要,因为更新需要对正在更新的记录进行排他锁,而 innodb 一次不会授予超过 1 个记录的排他锁。
【讨论】:
(针对某些 cmets)
在许多(不是所有)情况下,这是要遵循的模式:
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;
没有问题。该声明,无论您如何运行它,都是“原子的”。没有其他联系可以潜入并与您混淆。 (不过,它在逻辑上是幂等的,所以这不是问题。)
“不管”是指autocommit、BEGIN、tx_isolation_mode等
【讨论】: