1

当用户在我的网站上注册时,我使用 email_sent = 'NO' 在数据库中创建用户记录。然后我有一个 cron 作业,每隔几分钟发送一次欢迎电子邮件。它选择 email_sent = 'NO' 的所有用户记录并发送欢迎电子邮件。

如果电子邮件发送成功,则将用户记录更新为 email_sent='YES'。我的问题是,如何避免电子邮件发送成功但用户记录更新失败并且下次运行 cron 作业时会发送重复电子邮件的情况。即使我使用了数据库事务并且在发送电子邮件之前更新了记录但之后提交,如果提交失败,我也会遇到相同的情况,即发送重复的电子邮件。

另一种方法是将记录更新为 email_sent='YES' 并立即提交,然后尝试发送电子邮件。但是,如果电子邮件发送失败,则不会发送电子邮件。

有什么方法可以保证只发送一次电子邮件吗?我意识到由于许多外部因素,电子邮件传递最终可能会失败,但我只想确保我的 SMTP 服务器成功地将其推倒一次。

4

1 回答 1

1

您的评论指出提交没有失败,因此您可能担心风。

保持事务尽可能小,并让它失败,无论哪种方式在您的系统中更可接受......

BeginTransaction;
LookupRecord;

SendMail;

if(SentSuccessfully)
{
    UpdateRecord(Sent=True);
    CommitTransaction;
}
else
{
    RollbackTransaction;
}

或者,您可以更复杂地执行此操作,并且无需围绕电子邮件功能进行交易,但我认为这不是更好:

BeginTransaction;
LookupRecord;
UpdateRecord(Sent=True);
CommitTransaction;

SendMail;

if(!SentSuccessfully)
{
    UpdateRecord(Sent=False);
}

无论哪种方式,如果您有错误并且没有将正确的值提交给数据库,那么在不引入(可能不必要的)复杂性的情况下,您将无法避免它。你真的应该专注于使更新和事务坚如磐石,这样它就不会更新失败。

于 2012-07-31T21:24:24.327 回答