gpt4 book ai didi

php - 并行 cron 作业选取相同的 SQL 行

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

我基本上有一个 cron 文件,它在 cron 文件内同时向 1 个文件发送 multi_curl ,因此是并行的。

我的cron文件如下所示(发送并行请求)

<?php
require "files/bootstrap.php";
$amount = array(
"10","11","12","13","14"
);
$urls = array();
foreach($amount as $cron_id) {
$urls[] = Config::$site_url."single_cron.php?cron_id=".$cron_id;
}
$pg = new ParallelGet($urls);
?>

然后在我的 single_cron.php 中我得到以下查询

SELECT * 
FROM accounts C JOIN proxies P
ON C.proxy_id = P.proxy_id
WHERE C.last_used < DATE_SUB(NOW(), INTERVAL 1 MINUTE)
AND C.status = 1
AND C.running = 0
AND P.proxy_status = 1
AND C.test_account = 0
ORDER BY uuid()
LIMIT 1

即使我在查询中获得了uuid,它们似乎仍然以某种方式拾取同一行,防止这种情况的最佳方法是什么?我听说过一些关于交易

的事情

我当前使用的框架是 PHP,因此如果其中有任何解决方案可行,那么我可以自由选择解决方案。

最佳答案

检查select for update命令。这可以通过阻止其他并行查询来选择同一行,直到您执行 commit 。因此,您的选择应包含一些条件,例如 last_process_time > 60 ,您应该在选择该行后更新该行,并将 last_processed_time 设置为当前时间。也许您有不同的机制来检测最近是否选择/处理了一行,您也可以使用它。重要的是select for update将会在行上放置一个锁,因此即使您并行运行查询,它们也会被 mysql 服务器序列化。

这是确保您没有 2 个查询选择同一行的唯一方法 - 即使您通过 uuid() 进行的订单工作正常,您还是会时不时地在 2 个并行查询中选择同一行.

使用事务执行此操作的正确方法是:

START TRANSACTION;

SELECT *
FROM accounts C JOIN proxies P
ON C.proxy_id = P.proxy_id
WHERE C.last_used < DATE_SUB(NOW(), INTERVAL 1 MINUTE)
AND C.status = 1
AND C.running = 0
AND P.proxy_status = 1
AND C.test_account = 0
LIMIT 1;

(假设您的帐户表中有一个“ID”列用于唯一标识行)

UPDATE accounts
set last_used=now(), .... whatever else ....
where id=<insert the id you selected here>;

COMMIT;

将执行最先到达服务器的查询,并锁定返回的行。此时所有其他查询都将被阻止。现在您可以更新任何您想要的内容。提交后,来自其他进程的其他查询将被执行。他们不会找到您刚刚更改的行,因为 last_used < ...条件不再成立。其中一个查询将找到一行,锁定它,其他查询将再次被阻止,直到第二个进程执行提交。这一直持续到一切都完成。

而不是 START TRANSACTION ,您也可以在 session 中将 autocommit 设置为 0。并且不要忘记这仅在您使用 InnoDB 表时才有效。如果您需要更多详细信息,请查看我给您的链接。

关于php - 并行 cron 作业选取相同的 SQL 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20799844/

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