2012-07-31 84 views
1

当用户在我的网站上注册时,我使用email_sent ='NO'在数据库中创建了一个用户记录。然后,我有一个每隔几分钟发送一封欢迎邮件的cron作业。它选择email_sent ='NO'并发送欢迎邮件的所有用户记录。如何在发送电子邮件后提交“发送电子邮件”操作时避免发送重复电子邮件?

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

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

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

+0

为什么用户记录的更新失败?解决这个问题,你已经解决了你的问题。 – 2012-07-31 21:13:53

+0

您使用的是什么RDBMS,Oracle,SQL-Server,MySQL等?可能会有一些特定于数据库的内容可以提供帮助。 – Ben 2012-07-31 21:14:29

+0

除了Robert Harvey的评论之外 - 如果在更新已发送记录时提交失败,那么可以做的很少,以防止重复。如果cron依赖于数据库中的值,则该值必须可靠地更新。否则,你将不得不开发更复杂的方法来处理不一致的数据。 – Farray 2012-07-31 21:17:54

回答

1

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

保留交易尽可能的小,并有它失败无论怎样在你的系统更容易接受...

BeginTransaction; 
LookupRecord; 

SendMail; 

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

另外,您可以用更多的复杂性和不绕电子邮件功能的交易做到这一点,但我没有更好的看到这一点:

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

SendMail; 

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

无论哪种方式,如果有错误和正确的值不会提交到数据库中,有没有什么可以做,以避免它不引入(可能不必要)复杂性。你真的应该专注于使更新&事务稳定,所以它不会失败更新。