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

时间:2017-07-19 08:58:23

标签: mysql concurrency innodb

考虑下面的陈述

 var input = [1, 2, 3, 3, 4, 5,2, 6,3,6,1];
var current = input[0];
var found = false;
function removeDuplicate() {
    for (var i = 0; i < input.length; i++) {
        if (current == input[i]) {
            //found = false;
        } else if (current != input[i]) {
            console.log(" " + current);
            current = input[i];
            found = false;
        }
    }
    console.log(" " + current);

}
removeDuplicate();

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

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

2 个答案:

答案 0 :(得分:1)

不,它没有,因为更新需要对正在更新的记录进行独占锁定,并且innodb一次不会在记录上授予超过1个独占锁。

答案 1 :(得分: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;

没有问题。无论你如何运行它,这个陈述都是“原子的”。没有其他联系可以潜入并惹你。 (但是,它在逻辑上是幂等的,所以它不是问题。)

“不管”,我指的是autocommitBEGINtx_isolation_mode等。