当前位置: 首页 > 知识库问答 >
问题:

用MySQL数据库处理PHP Symfony中的队列竞争情况

马奇略
2023-03-14

我有一个应用程序在Symfony需要发送电子邮件/通知从应用程序。由于电子邮件/通知发送过程需要时间,所以我决定将它们放入队列中,并定期处理队列。因此,我可以减少涉及电子邮件/通知分派的请求的响应时间。

处理队列的Cron作业(一个php脚本-Symfony路由)每30秒运行一次,检查是否有未发送的电子邮件/通知,如果发现,它将从队列表中获取所有数据并开始发送它们。当发送电子邮件/通知时,队列表行状态标志将被更新,以显示它已发送。

现在,当有更多的电子邮件在队列中,可能需要超过30秒发送。另一个Cron作业也开始运行,并开始从队列发送电子邮件。从而导致发送重复的电子邮件/通知。

我的电子邮件队列表结构如下:

|-------------------------------------|
| id | email | body | status | sentat |
|-------------------------------------|

我解决这个问题的想法如下:

  1. 在数据库中设置Cron作业正在运行的标志,如果找到该标志集,则不应继续执行其他Cron作业。
  2. 将所有记录的状态更新为“已发送”,然后开始发送电子邮件/通知。

所以我的问题是,有没有什么高效的方法来处理队列?有什么Symfony捆绑包/特性来完成这样的特定任务吗?

共有2个答案

黎玺
2023-03-14

关于您的建议:

>

  • 如果cronjob进程死亡(无论出于什么原因)并且无法清理标志,该怎么办?我认为旗子不是个好主意。如果您希望遵循这种方法,则不应使用布尔值,而应使用进程ID或时间戳,这样您就可以检查进程是否仍然存在,或者它是否在很久以前就开始了,而没有进行清理。

    同样的问题:如果进程死了怎么办?您不希望在邮件发送之前将其标记为已发送。

    我想我可能会使用两个字段:一个用于将一条记录标记为“发送中进行”(从而告诉其他进程跳过此记录),另一个用于将其标记为“发送成功完成”。我会给这两个都写一个时间戳,这样我就可以(自动或手动)找到那些“正在进行中的发送”在过去大于X秒的记录,这将是一个已死亡进程的指示器。

  • 家志学
    2023-03-14

    所以我的问题是,有没有什么高效的方法来处理队列?有什么Symfony捆绑包/特性来完成这样的特定任务吗?

    您可以采用排队束加dbal运输。

    它已经照顾到种族条件和其他东西。

     类似资料:
    • 问题内容: 我有几个工作人员,每个工作人员都拥有与PostgreSQL的连接。工人用不同的桌子操纵。 工作人员处理来自系统外部的并行请求。被访问的表之一是用户表。当收到一些信息时,我首先需要确保表中有该用户的记录。如果没有记录,我希望首先创建一个。 我正在使用以下成语: 的代码是: 然后测试是否返回任何行。 的(简化)代码为: 当我的系统处理与 同一 用户有关 的 不同信息的并行流时,我经常会收到

    • 问题内容: 我有一个订单队列,可通过存储过程由多个订单处理器访问。每个处理器传递一个唯一的ID,该ID用于锁定接下来的20个订单以供自己使用。然后,存储过程将这些记录返回给要处理的订单处理器。 在某些情况下, 多个处理器能够检索相同的“ OrderTable”记录 ,此时它们将尝试同时对其进行操作。这最终会导致在该过程的后期引发错误。 我的下一个动作是允许每个处理器抓住所有可用的订单,然后对处理器

    • 在使用ACK时,有没有一种简单的方法实现类似于“锁定”的东西来防止RabbitMQ队列中的竞争条件? 我有以下问题--我有几个客户机使用ACK使用队列。每当客户端收到消息时,他就会确认并处理消息。但是,如果由于某种原因处理失败,我希望消息返回到队列。

    • 问题内容: 如何停止MySQL中的竞争条件?当前的问题是由一个简单的算法引起的: 从表中选择一行 如果不存在,将其插入 然后会得到重复的行,或者如果您通过唯一/主键阻止它,则会出现错误。 现在,通常我认为事务在这里有所帮助,但是由于该行不存在,所以事务实际上并没有帮助(或者我是否错过了什么?)。 LOCK TABLE听起来有些矫kill过正,尤其是如果该表每秒更新多次。 我唯一想到的其他解决方案是

    • 问题内容: 我正在开发的应用程序中存在潜在的竞争状况,我想在查询中考虑和避免这种情况。 总结应用程序流程… 在表中创建一个新行: 通过查看对时间敏感的表格,找出Bar先生是否是获胜者: 如果他是赢家,请相应地更新他的条目行: 由于每个奖项只能颁发一次,因此我需要消除比赛条件的任何可能性,在这种情况下,另一个过程可以查询奖项表并更新上述步骤2和3之间的条目表。 我一直在做一些研究,发现了大量关于事务

    • 问题内容: 当两个连接要更新同一条记录时,如何防止MySQL数据库中的竞争状况? 例如,连接1要增加“尝试”计数器。第二个连接也想这样做。两个连接都“尝试”计数,增加值,两个“尝试” 都增加值。突然,“ tries”仅是“ tries + 1”,而不是“ tries + 2”,因为两个连接都具有相同的“ tries”并将其增加1。 如何解决这个问题呢? 问题答案: 这是3种不同的方法: 原子更新