如何在PHP和MySQL中使电子邮件具有事务性?

如何在PHP和MySQL中使电子邮件具有事务性?,php,mysql,transactions,Php,Mysql,Transactions,我想向我的应用程序用户发送电子邮件,确保每封电子邮件只发送一次。 我将在数据库中记录电子邮件传输。 如果我使用此操作顺序: 插入数据库 发送电子邮件 承诺 脚本有可能在发送电子邮件之后(步骤2)和执行提交之前(步骤3)超时。在这种情况下,将不会提交步骤1中的更改,并且电子邮件发送作业将无法知道上次成功发送了电子邮件,因此将再次发送相同的电子邮件 有办法吗?还是我必须忍受偶尔重复的电子邮件 您可以创建一列status,该列可以是enum或int,其值表示发送、失败、成功发送 现在,您可以这样做:

我想向我的应用程序用户发送电子邮件,确保每封电子邮件只发送一次。 我将在数据库中记录电子邮件传输。 如果我使用此操作顺序:

  • 插入数据库
  • 发送电子邮件
  • 承诺
  • 脚本有可能在发送电子邮件之后(步骤2)和执行提交之前(步骤3)超时。在这种情况下,将不会提交步骤1中的更改,并且电子邮件发送作业将无法知道上次成功发送了电子邮件,因此将再次发送相同的电子邮件


    有办法吗?还是我必须忍受偶尔重复的电子邮件

    您可以创建一列
    status
    ,该列可以是
    enum
    int
    ,其值表示
    发送、失败、成功发送

    现在,您可以这样做:

  • 在发送邮件之前插入数据。并将
    状态
    设置为
    发送
  • 寄信
  • 根据步骤(2)中的结果,
    更新
    失败
    发送成功

  • 如果
    尝试
    ,您可能还希望有一列
    尝试
    ,以及一个每30分钟发送
    失败的
    邮件的批处理过程。然后,将
    状态设置为
    失败
    发送成功
    并记录错误。

    您可以创建一列
    状态
    ,该列可以是
    枚举
    int
    ,其值表示
    发送、失败、成功发送

    现在,您可以这样做:

  • 在发送邮件之前插入数据。并将
    状态
    设置为
    发送
  • 寄信
  • 根据步骤(2)中的结果,
    更新
    失败
    发送成功

  • 如果
    尝试
    ,您可能还希望有一列
    尝试
    ,以及一个每30分钟发送
    失败的
    邮件的批处理过程。然后,将
    状态设置为
    永久失败
    成功发送
    并记录错误。

    您可以使用MySQL事务来完成此操作,基本上它会准备所有查询,并在您要求时执行查询

    因此,您在发送邮件之前准备查询,然后在发送邮件之后提交查询

    更多信息


    或者,您可以将邮件设置为挂起,然后将其更新为已完成。然后运行一个cron作业,杀死已经运行了一定时间的挂起作业,或者尝试重新处理它们。

    您可以使用MySQL事务进行此操作,基本上它会准备所有查询,并在您要求它这样做时执行它们

    因此,您在发送邮件之前准备查询,然后在发送邮件之后提交查询

    更多信息


    或者,您可以将邮件设置为挂起,然后将其更新为已完成。然后运行一个cron作业,杀死已经运行了一定时间的挂起作业,或者尝试重新处理它们。

    长话短说:您不能使电子邮件具有事务性

    充其量您知道您的smtp服务器已收到您发送邮件的请求。但是,您无法知道它是被发送、接收还是被退回


    所以,正如你已经建议的那样,你最好的办法就是偶尔重复发送电子邮件。无论如何,这将是一个非常罕见的事件。

    长话短说:你不能让电子邮件具有事务性

    充其量您知道您的smtp服务器已收到您发送邮件的请求。但是,您无法知道它是被发送、接收还是被退回


    所以,正如你已经建议的那样,你最好的办法就是偶尔重复发送电子邮件。无论如何,这将是一个非常罕见的事件。

    我刚刚有时间思考我自己的问题。以下是我现在的想法:

    有关的电子邮件发送步骤包括:

  • 插入数据库
  • 发送电子邮件
  • 承诺
  • 电子邮件不能成为事务性的,因为第2步(以上)不是事务的一部分,即使它是在事务处于活动状态时完成的

    这些步骤有助于确保重试任何失败的电子邮件发送尝试,但不能保证电子邮件不会发送多次。只有当电子邮件发送引擎能够感知事务时,这种情况才能得到改善。这样的发动机(至少)会执行以下操作:

  • 接受电子邮件作业提交,但在执行提交之前不发送电子邮件
  • 如果电子邮件未发送,则使提交失败
  • 如果事务回滚,则取消提交的作业
  • 我不知道有任何这样的电子邮件服务器

    Nishant在其建议的以下步骤中:

  • 在发送邮件之前插入数据。并将状态设置为发送
  • 寄信
  • 根据步骤(2)中的结果,更新行失败或成功发送
  • 由于脚本超时,这些步骤也无法确保重复发送电子邮件,原因与上述相同


    到目前为止,我想,我将不得不忍受偶尔重复的电子邮件。

    只是有时间思考我自己的问题。以下是我现在的想法:

    有关的电子邮件发送步骤包括:

  • 插入数据库
  • 发送电子邮件
  • 承诺
  • 电子邮件不能成为事务性的,因为第2步(以上)不是事务的一部分,即使它是在事务处于活动状态时完成的

    这些步骤有助于确保重试任何失败的电子邮件发送尝试,但不能保证电子邮件不会发送多次。只有当电子邮件发送引擎能够感知事务时,这种情况才能得到改善。这样的发动机(至少)会执行以下操作:

  • 接受电子邮件作业提交,但在提交之前不要发送电子邮件