我正面临着发送电子邮件的时间表问题。让我解释一下。由于php没有多线程,我决定在同一个地运行3个脚本(a1.php,a2.php,a3.php,都是一样的)在同桌上的时间。 表:email_job id:唯一但不是inocmental(随机)文本字段 email_text:文本字段 状态:待定/发 update_time:datetime字段 当我使用a1.php读取100封电子邮件(status = pending)时,同时另外2个(a2.php,a3.php)脚本也读取相同的100封电子邮件,因为status = pending。 有时3个脚本读取相同的数据,因此发送重复的电子邮件。 是否可以将数据锁定在读取级别,假设a1.php读取50行并锁定这些行,直到状态发生变化,因此其他脚本将读取处于挂起状态的其他行而不是锁定行... 我如何防止重复发送,我需要使用许多脚本,因为我需要在第二个发送许多电子邮件? 注意:我使用php,mysql,如果可能的话给代码。这里可能是电子邮件/短信/其他人在短时间内发送大量邮件。
答案 0 :(得分:0)
在数据库条目上添加visited
标志。
每个脚本都需要在处理条目之前读取标志,如果是1
则将其设置为0
,因此其他脚本将省略该条目。
答案 1 :(得分:0)
在表格中添加一列,如下所示。
processed_by int(11) not null default 0
然后,每个处理脚本都可以运行此循环:
update table set processed_by = CONNECTION_ID() where processed_by = 0 limit 1
select * from table where processed_by = CONNECTION_ID()
update table set processed_by = -CONNECTION_ID() where processed_by = CONNECTION_ID()
当第一步返回行计数为零时,您将跳出循环(意味着表中没有未处理的条目。
表中processed_by
值为零的行正在等待处理。具有正值的行当前在处理中是活动的,具有负值的行是完整的。
步骤1只选择一行进行处理。它可以扩展到无限数量的并行运行的脚本:每个脚本都有自己的CONNECTION_ID值。
编辑,在评论中指定了每分钟100K消息的吞吐量。这非常大,特别是如果它是24x7基本负载要求。它需要做大量工作才能扩展您的SMTP服务器基础架构以处理这种负载。
我建议的解决方案的容量可以扩大;我指定了一批大小的批次。更大的批次将起作用。这是对我的建议的修改。
update table set processed_by = CONNECTION_ID() where processed_by = 0 limit 500
UPDATE
请求没有影响任何行,请暂停几秒钟。select * from table where processed_by = CONNECTION_ID()
update table set processed_by = -CONNECTION_ID() where processed_by = CONNECTION_ID()
这是有效的,因为当连接到同一数据库服务器的多个程序使用时,第一步中的UPDATE请求没有竞争条件。
在评论中,有人建议使用批量电子邮件服务(如Mandrill)。这是一个很好的建议:您需要为他们的专业知识付费,以便在整个地方可靠地传递信息。 Mandrill提供每月最多12,000封邮件的免费套餐。