gpt4 book ai didi

PHP:如何防止代码的多次执行(如果它已经在进行中)

转载 作者:IT老高 更新时间:2023-10-29 00:14:57 28 4
gpt4 key购买 nike

说明

通常需要 10-20 秒响应的 API 调用(对另一个服务)存储在数据库中,

存储后,系统会立即尝试使用API​​向用户显示结果,但可能会失败(并显示失败但我们会自动重试),因此还有一个Cron作业设置为每 30 秒运行一次并再次尝试(失败的)查询。

如果 API 返回成功(无论是即时使用还是使用 Cron Job),则该标志在数据库中更改为成功,并且不会再次运行。

问题

我的问题是当对 API 的 Instant Call 正在进行时,Cron Job 可能还会尝试另一个调用,因为它尚未标记为成功,

同样在极少数情况下,当上一个 Cron Job 正在进行时,下一个 Cron Job 可能会再次运行代码。

我已经尝试过什么来防止这个问题

我尝试将 In Process API 调用存储在 Status=1 的数据库表中,并在 API 调用成功时删除它们,如果失败则将状态设置为 0,

 if ($status === 0)
{

// Set Status to 1 in Database First (or die() if database update failed)

// Then Call The API

// If Failed Set Status to 0 so Cron Job can try again

// If Successful Change Flag to success and remove from queue

}

But what if the Instant Call and the Cron Job Call happen at the exact same time? they both check if status is 0 which it is, then both set status to 1 and execute the API Call...

问题

  1. 我尝试过的处理方法是否正确?

  2. 如果有很多调用(有时 +500/秒),我是否应该担心它们会在确切的时间发生(我在上面的黄色引用中解释的问题)

赏金前更新

难道真的没有一种简单的方法可以在 PHP 端处理此类情况吗?如果不是,专家认为哪种方式更好?下面是一些方法,但没有一个足够详细,也没有一个有任何反对票/赞成票。

附:数据库有很多更新/插入,我不认为锁定是一个有效的想法,我不确定其余的想法。

最佳答案

这正是 Semaphore 的原因为。

在php中,可以通过以下方式使用:在 PHP 中使用信号量实际上非常简单。信号量函数只有 4 个:

sem_acquire() – Attempt to acquire control of a semaphore.
sem_get() – Creates (or gets if already present) a semaphore.
sem_release() – Releases the a semaphore if it is already acquired.
sem_remove() – Removes (deletes) a semaphore.

那么它们是如何协同工作的呢?

  1. 首先,调用 sem_get() 来获取信号量的标识符。
  2. 之后,您的一个进程将调用 sem_acquire() 来尝试获取信号量。如果当前不可用,sem_acquire() 将阻塞,直到信号量被另一个进程释放。
  3. 获取信号量后,您可以访问您使用它控制的资源。
  4. 完成资源后,调用 sem_release() 以便另一个进程可以获取信号量。
  5. 当一切都说完了,并且您确定您的进程不再需要信号量时,您可以调用 sem_remove() 来完全删除信号量。

您可以在 this article 中找到更多信息和示例。 .

关于PHP:如何防止代码的多次执行(如果它已经在进行中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30550663/

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