发送电子邮件后,当我提交“发送电子邮件”操作时,如何避免发送重复的电子邮件?

时间:2012-07-31 21:10:29

标签: database email distributed-transactions

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

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

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

有没有办法确保一旦发送电子邮件?我意识到由于许多外部因素,电子邮件传递最终可能会失败,但我只是想确保我的SMTP服务器成功将其推迟一次。

1 个答案:

答案 0 :(得分:1)

您的评论表明提交没有失败,因此您可能会担心风。

保持交易尽可能小,并使其失败,无论您的系统更容易接受哪种方式......

BeginTransaction;
LookupRecord;

SendMail;

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

或者你可以更复杂,没有关于电子邮件功能的交易,但我不认为这更好:

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

SendMail;

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

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