Я хочу отправить электронное письмо своим пользователям приложений, чтобы каждое электронное письмо отправлялось только один раз. Я буду записывать электронную почту в базе данных. Если я использую этот порядок операций:
Существует вероятность того, что script истечет сразу после отправки электронной почты (шаг № 2) и перед выполнением фиксации (шаг № 3). В этом случае изменение шага № 1 не будет выполнено, и задание по отправке электронной почты не сможет узнать, что письмо было успешно отправлено в последний раз, чтобы снова отправить электронное письмо.
Есть ли выход или мне приходится жить со случайными дублирующими письмами?
Просто подумал над своим вопросом. Вот что я думаю сейчас:
Задачами отправки электронной почты были:
Электронная почта не может быть выполнена транзакцией, потому что шаг № 2 (выше) не является частью транзакции, даже если она выполняется во время транзакции.
Эти шаги могут помочь избежать повторных попыток отправки по электронной почте, но не могут гарантировать, что электронное письмо не отправляется более одного раза. Эта ситуация может быть улучшена только в том случае, если движок отправки электронной почты связан с транзакциями. Такой двигатель мог бы (по крайней мере) сделать следующее:
Я не знаю о таком сервере электронной почты.
Нишант в своем ответе предложил следующие шаги:
- Вставьте данные перед отправкой почты. И установите статус отправки
- Отправить письмо
- на основе результата на шаге (2), обновить строку либо неудачно, либо отправлено успешно.
Эти шаги также не могут обеспечить повторную отправку электронной почты из-за истечения времени ожидания script по той же причине, что указано выше.
До сих пор, я думаю, мне просто придется жить со случайными дублирующимися письмами.
Короче говоря: вы не можете совершать транзакции по электронной почте.
В лучшем случае вы знаете, что ваш SMTP-сервер получил ваш запрос на отправку сообщения. Однако у вас нет способа узнать, было ли оно отправлено, получено или отскочено.
Таким образом, ваш лучший выбор, как вы уже сказали, состоит в том, чтобы периодически воспроизводить повторяющиеся электронные письма. В любом случае это будет очень редкое событие.
Вы можете использовать транзакции MySQL для этого, в основном он подготавливает все ваши запросы и выполняет их, когда вы говорите ему об этом.
Итак, вы готовите запросы перед отправкой почты, а затем отправляете ее после отправки.
Дополнительная информация
http://dev.mysql.com/doc/refman/5.0/en/commit.html
В качестве альтернативы вы можете настроить почту как ожидающую, а затем обновить ее как завершенную. Затем запустите задание cron, которое убивает ожидающие задания, которые выполнялись в течение определенного времени, или попытайтесь их обработать.
хорошо вы можете сделать столбец status
, который может быть enum
или int
со значениями, представляющими sending, failed, sent_successfully
Теперь вы делаете это:
status
в sending
update
строки либо failed
, либо sent_successfully
.Вам также может понравиться столбец tries
и пакетный процесс, который отправляет письма failed
каждые 30 минут, если tries < TRY_THRESHOLD
. Затем установите status
в failed_permanently
или sent_successfully
и запишите ошибку.
try / catch
для работы с таймаутами.