MySQL 唯一行交换是原子的吗?

Is MySQL unique row swap atomic?

我得出的结论是,在要交换的值是唯一约束的一部分的情况下,交换两行的唯一方法是将第 1 行更新为正常范围之外的临时值(例如INT 列的负数),将第 2 行更改为第 1 行的先前值,并将第 1 行更改为第 2 行的先前值。

简化示例:

SELECT uniquevalue1 AS prev1 FROM sometable;
SELECT uniquevalue2 AS prev2 FROM sometable;

UPDATE sometable SET uniquevalue1=-1;
UPDATE sometable SET uniquevalue2=[prev1];
UPDATE sometable SET uniquevalue1=[prev2];

随后提交。

这工作正常,没问题,但是:

这个操作安全吗?

想象一下默认(带符号)INT(11) 列的唯一约束,您可以在其中临时交换为 -1,然后遵循上述模式 - 当然禁用自动提交。

如果同时执行这两个交换操作会怎样?缺少commit until after -1不再是任何行的值是否意味着语句不会发生冲突?

您不能同时执行两个或多个语句。他们总是一一执行。

但是,如果您使用事务(备注:这只适用于 innodb 类型的表,不适用于 myisam),此选项要么失败且没有任何更改,要么成功。同样尝试使用数字 -1 的第二个交换将被锁定,直到第一个事务完成。