【发布时间】:2021-04-27 16:04:24
【问题描述】:
我有一个查询,它使用变量 LIMIT 更新表中的多行。我需要从更新的行中获取数据,以便知道哪些确切的行受到了影响。我写了这个简单的程序:
DELIMITER $$
CREATE PROCEDURE select_update(IN myId INT, IN myAttr VARCHAR(10), IN myAmount MEDIUMINT)
begin
SELECT data FROM mytable WHERE id IS NULL AND attr = myAttr LIMIT myAmount;
UPDATE mytable SET id = myId WHERE id IS NULL AND attr = myAttr LIMIT myAmount;
end$$
DELIMITER ;
此 SELECT 语句是否总是返回与 UPDATE 语句影响的完全相同的行?其他用户是否可以在此过程运行时执行查询,从而可能在 SELECT 和 UPDATE 之间更改受影响的行?
【问题讨论】:
-
这些不在事务中。
select和update之间可能会发生数据库更改。换句话说,这段代码有竞争条件。 -
@GordonLinoff 如果我在事务中调用该过程会怎样?
-
LIMIT参数必须是文字,您不能在那里使用变量。此外,没有ORDER BY的LIMIT返回不可预测的结果,不能保证SELECT和UPDATE将处理相同的行。 -
如果它在事务中,请将
FOR UPDATE子句添加到SELECT查询中,这样它将锁定它搜索的所有行。 -
@Barmar,“在存储的程序中,可以使用整数值例程参数或局部变量指定 LIMIT 参数。” dev.mysql.com/doc/refman/8.0/en/select.html