I want to send email to my app users ensuring that every email is sent only once.
I will be recording the email transmission in a database.
If I use this order of operations:
- Insert into database
- Send email
- Commit
There is a chance that script times out just after sending the email (step #2) and before doing the commit (step #3). In that case the change in step #1 will not be committed and email sending job won’t be able to know that the email was successfully sent last time so the same email will be sent again.
Is there a way out or do I have to live with occasional duplicate emails?
Just got some time to think over my own question. Here is what I think now:
The email sending steps in question were:
Email cannot be made transactional because the step #2 (above) is not part of the transaction even though it is done while the transaction is active.
These steps can help ensure that any failed email-sending attempts is retried but cannot guarantee that an email is not sent more than once. This situation could only be improved if the email sending engine is transaction-aware. Such an engine would (atleast) do the following:
I am not aware of any such email server.
Nishant, in his answer suggested following steps:
These steps also cannot ensure duplicate sending of email due to script timeout for the same reason as noted above.
So far, I think, I will just have to live with occasional duplicate emails.