如何在PHP和MySQL中使电子邮件具有事务性?
我想向我的应用程序用户发送电子邮件,确保每封电子邮件只发送一次。 我将在数据库中记录电子邮件传输。 如果我使用此操作顺序:如何在PHP和MySQL中使电子邮件具有事务性?,php,mysql,transactions,Php,Mysql,Transactions,我想向我的应用程序用户发送电子邮件,确保每封电子邮件只发送一次。 我将在数据库中记录电子邮件传输。 如果我使用此操作顺序: 插入数据库 发送电子邮件 承诺 脚本有可能在发送电子邮件之后(步骤2)和执行提交之前(步骤3)超时。在这种情况下,将不会提交步骤1中的更改,并且电子邮件发送作业将无法知道上次成功发送了电子邮件,因此将再次发送相同的电子邮件 有办法吗?还是我必须忍受偶尔重复的电子邮件 您可以创建一列status,该列可以是enum或int,其值表示发送、失败、成功发送 现在,您可以这样做:
有办法吗?还是我必须忍受偶尔重复的电子邮件 您可以创建一列
status
,该列可以是enum
或int
,其值表示发送、失败、成功发送
现在,您可以这样做:
状态
设置为发送
更新
行失败
或发送成功
如果
尝试
,您可能还希望有一列尝试
,以及一个每30分钟发送失败的邮件的批处理过程。然后,将状态设置为失败
或发送成功
并记录错误。您可以创建一列状态
,该列可以是枚举
或int
,其值表示发送、失败、成功发送
现在,您可以这样做:
在发送邮件之前插入数据。并将状态
设置为发送
寄信
根据步骤(2)中的结果,更新
行失败
或发送成功
如果尝试
,您可能还希望有一列尝试
,以及一个每30分钟发送失败的邮件的批处理过程。然后,将状态设置为永久失败
或成功发送
并记录错误。您可以使用MySQL事务来完成此操作,基本上它会准备所有查询,并在您要求时执行查询
因此,您在发送邮件之前准备查询,然后在发送邮件之后提交查询
更多信息
或者,您可以将邮件设置为挂起,然后将其更新为已完成。然后运行一个cron作业,杀死已经运行了一定时间的挂起作业,或者尝试重新处理它们。您可以使用MySQL事务进行此操作,基本上它会准备所有查询,并在您要求它这样做时执行它们
因此,您在发送邮件之前准备查询,然后在发送邮件之后提交查询
更多信息
或者,您可以将邮件设置为挂起,然后将其更新为已完成。然后运行一个cron作业,杀死已经运行了一定时间的挂起作业,或者尝试重新处理它们。长话短说:您不能使电子邮件具有事务性
充其量您知道您的smtp服务器已收到您发送邮件的请求。但是,您无法知道它是被发送、接收还是被退回
所以,正如你已经建议的那样,你最好的办法就是偶尔重复发送电子邮件。无论如何,这将是一个非常罕见的事件。长话短说:你不能让电子邮件具有事务性
充其量您知道您的smtp服务器已收到您发送邮件的请求。但是,您无法知道它是被发送、接收还是被退回
所以,正如你已经建议的那样,你最好的办法就是偶尔重复发送电子邮件。无论如何,这将是一个非常罕见的事件。我刚刚有时间思考我自己的问题。以下是我现在的想法:
有关的电子邮件发送步骤包括:
插入数据库
发送电子邮件
承诺
电子邮件不能成为事务性的,因为第2步(以上)不是事务的一部分,即使它是在事务处于活动状态时完成的
这些步骤有助于确保重试任何失败的电子邮件发送尝试,但不能保证电子邮件不会发送多次。只有当电子邮件发送引擎能够感知事务时,这种情况才能得到改善。这样的发动机(至少)会执行以下操作:
接受电子邮件作业提交,但在执行提交之前不发送电子邮件
如果电子邮件未发送,则使提交失败李>
如果事务回滚,则取消提交的作业
我不知道有任何这样的电子邮件服务器
Nishant在其建议的以下步骤中:
在发送邮件之前插入数据。并将状态设置为发送
寄信
根据步骤(2)中的结果,更新行失败或成功发送
由于脚本超时,这些步骤也无法确保重复发送电子邮件,原因与上述相同
到目前为止,我想,我将不得不忍受偶尔重复的电子邮件。只是有时间思考我自己的问题。以下是我现在的想法:
有关的电子邮件发送步骤包括:
插入数据库
发送电子邮件
承诺
电子邮件不能成为事务性的,因为第2步(以上)不是事务的一部分,即使它是在事务处于活动状态时完成的
这些步骤有助于确保重试任何失败的电子邮件发送尝试,但不能保证电子邮件不会发送多次。只有当电子邮件发送引擎能够感知事务时,这种情况才能得到改善。这样的发动机(至少)会执行以下操作:
接受电子邮件作业提交,但在提交之前不要发送电子邮件