gpt4 book ai didi

php - cron 上的 MySQL 查询重叠,忽略 'locked' 行

转载 作者:行者123 更新时间:2023-11-29 13:36:20 26 4
gpt4 key购买 nike

我试图将表中的一行锁定为“正在使用”,这样当我的 cron 每分钟运行时,我就不会处理数据两次。由于我的脚本运行所需的时间较长,cron 将导致脚本的多个实例同时运行(通常一次大约 5 或 6 个)。由于某种原因,我的“使用中”方法并不总是有效。

我确实不想想要锁定表,因为我需要它们可用于同时处理,这就是为什么我采用了使用“inuse”字段伪锁定各个行的方法。我不知道有更好的方法来做到这一点。

这是我的困境的说明:

 <?
//get the first row from table_1 that is not in use
$result = mysqli_query($connect,"SELECT * FROM `table_1` WHERE inuse='no'");
$rows = mysqli_fetch_array($result, MYSQLI_ASSOC);
$data1 = $rows[field1];

//"lock" our row by setting inuse='yes'
mysqli_query($connect,"UPDATE `table_1` SET inuse='yes' WHERE field1 = '$data1'");

//insert new row into table_2 with our data if it doesn't already exist
$result2 = mysqli_query($connect,"SELECT * FROM `table_2` WHERE field='$data2'");
$numrows = mysqli_num_rows($result2);
if($numrows >= 1) {
//do nothing
} else {
//run some unrelated script to get data
$data2 = unrelatedFunction();

//insert our data into table_2
mysqli_query($connect,"INSERT INTO `table_2` (field) value ('$data2')");
}

//"unlock" our row in table_1
mysqli_query($connect,"UPDATE `table_1` SET inuse='no' WHERE field1 = '$data1'");
?>

您将在这里看到,如果 $data2 已存在一行,则不会收集和插入 $data2,但该部分用于错误检查,并且不会回答我的问题,因为错误仍然发生。我试图理解为什么(如果我没有在那里进行错误检查)我的“inuse”方法有时会被忽略,并且我在 table_2 中收到重复的行,其中包含 $data2 。

最佳答案

在第一次选择和第一次更新之间有很多时间,另一个进程可以执行相同的操作。您也没有使用事务,因此您不能保证其他人可以看到更改的任何顺序。

您可以将所有内容移至具有所需隔离级别的事务中,并使用SELECT .... FOR UPDATE syntax 。或者您可以尝试以不同的方式进行复制。例如,更新您要处理的 N 行并 SET in_use=your_current_pid WHERE in_use IS NULL。然后,您可以读回手动标记为要处理的行。完成后,将 in_use 重置为 NULL

关于php - cron 上的 MySQL 查询重叠,忽略 'locked' 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18689060/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com