我想向我的应用用户发送电子邮件,确保每封电子邮件只发送一次。 我将在数据库中记录电子邮件传输。 如果我使用这个操作顺序:
在发送电子邮件(步骤#2)之后和执行提交之前(步骤#3),脚本有可能超时。在这种情况下,步骤#1中的更改将不会被提交,并且电子邮件发送作业将无法知道上次成功发送电子邮件,因此将再次发送相同的电子邮件。
是否有出路或者我是否需要偶尔使用重复的电子邮件?
答案 0 :(得分:3)
简而言之:您无法进行电子邮件交易。
充其量,您知道您的smtp服务器已收到您发送邮件的请求。但是你无法知道它是被发送,接收还是被退回。
所以,正如您已经建议的那样,最好的选择是偶尔使用重复的电子邮件。无论如何,这将是一个非常罕见的事件。
答案 1 :(得分:2)
你可以使用MySQL事务,基本上它会准备好你的所有查询并在你告诉它时执行它们。
所以你在发送邮件之前准备好查询,然后在发送邮件之后提交它。
更多信息
http://dev.mysql.com/doc/refman/5.0/en/commit.html
或者,您可以将邮件设置为待处理,然后将其更新为已完成。然后运行一个cron作业,该作业会终止已经运行了一段时间的挂起作业,或者尝试重新处理它们。
答案 2 :(得分:1)
您可以制作一个status
或enum
列int
,其值为sending, failed, sent_successfully
现在,你这样做:
status
设置为sending
update
行failed
或sent_successfully
。您可能还希望有一个列tries
和一个批处理流程,如果failed
,则每30分钟发送一次tries < TRY_THRESHOLD
个邮件。然后,将status
设置为failed_permanently
或sent_successfully
并记录错误。
答案 3 :(得分:0)
只是有时间思考我自己的问题。以下是我现在的想法:
有问题的电子邮件发送步骤是:
电子邮件不能成为事务性的,因为步骤#2(上面)不是事务的一部分,即使它是在事务处于活动状态时完成的。
这些步骤有助于确保重试任何失败的电子邮件发送尝试,但无法保证不会多次发送电子邮件。如果电子邮件发送引擎具有事务感知功能,则只能改善这种情况。这样的引擎会(至少)执行以下操作:
我不知道有任何此类电子邮件服务器。
Nishant,answer建议采取以下步骤:
- 在发送邮件之前插入数据。并将状态设置为发送
- 发送邮件
- 根据步骤(2)中的结果,更新行失败或发送成功。
醇>
由于脚本超时,这些步骤也无法确保重复发送电子邮件,原因与上述相同。
到目前为止,我认为,我只需要偶尔使用重复的电子邮件。