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

Database 当我提交“电子邮件”时,如何避免发送重复的电子邮件;“已发送电子邮件”;发送电子邮件后的操作?,database,email,distributed-transactions,Database,Email,Distributed Transactions,当用户在我的网站上注册时,我会在数据库中创建一个用户记录,email_sent='NO'。然后我有一个cron工作,每隔几分钟发送欢迎电子邮件。它选择电子邮件发送=否的所有用户记录并发送欢迎电子邮件 如果电子邮件发送成功,则会将用户记录更新为电子邮件“发送=”是“。我的问题是,如何避免电子邮件成功发送但用户记录更新失败,并且下次cron作业运行时发送重复电子邮件的情况。即使我使用了数据库事务,并且在发送电子邮件之前更新了记录,但之后提交了,如果提交失败,我也会遇到发送重复电子邮件的相同情况 另一

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

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

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


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

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

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

BeginTransaction;
LookupRecord;

SendMail;

if(SentSuccessfully)
{
    UpdateRecord(Sent=True);
    CommitTransaction;
}
else
{
    RollbackTransaction;
}
或者,您可以更复杂地执行此操作,而不需要电子邮件功能的交易,但我并不认为这更好:

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

SendMail;

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

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

你的评论说提交没有失败,所以你可能会担心风

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

BeginTransaction;
LookupRecord;

SendMail;

if(SentSuccessfully)
{
    UpdateRecord(Sent=True);
    CommitTransaction;
}
else
{
    RollbackTransaction;
}
或者,您可以更复杂地执行此操作,而不需要电子邮件功能的交易,但我并不认为这更好:

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

SendMail;

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

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

为什么用户记录的更新失败了?解决了这个问题,你就解决了你的问题。你用的是什么关系数据库管理系统,Oracle,SQL Server,MySQL等等?很可能会有一些特定于数据库的东西可以提供帮助。罗伯特·哈维(Robert Harvey)进一步评论说,如果您在更新发送的记录时提交失败,那么几乎无法防止重复。如果cron依赖于数据库中的某个值,则必须可靠地更新该值。否则,您将不得不开发更复杂的方法来处理不一致的数据。目前还没有失败,但我有点偏执,担心它会失败。@user1566921您可以设置一个日志来查看发送重复电子邮件的频率吗?然后您可以查看实际的重复率是否高于{AcceptableRate}。为什么用户记录更新失败?解决了这个问题,你就解决了你的问题。你用的是什么关系数据库管理系统,Oracle,SQL Server,MySQL等等?很可能会有一些特定于数据库的东西可以提供帮助。罗伯特·哈维(Robert Harvey)进一步评论说,如果您在更新发送的记录时提交失败,那么几乎无法防止重复。如果cron依赖于数据库中的某个值,则必须可靠地更新该值。否则,您将不得不开发更复杂的方法来处理不一致的数据。目前还没有失败,但我有点偏执,担心它会失败。@user1566921您可以设置一个日志来查看发送重复电子邮件的频率吗?然后您可以看到实际的重复率是否高于{AcceptableRate}。