Как гарантировать, что строка БД обновляется только один раз?

#mysql

#mysql

Вопрос:

Я создал очередь электронной почты в таблице базы данных (MySQL). Каждая строка представляет собой сообщение электронной почты с указанием получателя, отправителя и т.д. И скрипт автоматически вызывается каждую минуту, и он извлекает неотправленные сообщения и отправляет их, а для столбца «отправлено» каждого сообщения устанавливается значение true.

Мне нужно убедиться, что каждое сообщение отправляется только один раз. Но если скрипт выполняется долго, другой скрипт может извлекать сообщения и отправлять их, не зная, что они будут отправлены другим скриптом.

В настоящее время я ограничиваю количество строк до 50 за раз, чтобы сократить время выполнения скрипта. Но это не гарантирует. Я уверен, что есть лучший способ.

Спасибо.

Сэм

Ответ №1:

Создать надежную очередь заданий непросто. Вам определенно нужно хранить больше информации, чем «отправлено / не отправлено». Минимальный минимум, о котором я могу думать, это «Дата взятия» и «Дата отправки». Процесс доставки должен:

  1. Выберите несколько доступных сообщений:
     START TRANSACTION;
    
    SELECT message_id
    FROM message
    WHERE date_taken IS NULL AND date_sent IS NULL
    ORDER BY message_id
    LIMIT 5
    FOR UPDATE;
     
  2. Пометьте их как обработку:
     UPDATE message
    SET date_taken=NOW()
    WHERE message_id IN (101, 102, 103, 104, 105);
    
    COMMIT;
     
  3. После завершения пометьте их как отправленные:
     UPDATE message
    SET date_sent=NOW()
    WHERE message_id IN (101, 102, 103, 104, 105);
     

Вам также нужно будет выпускать сообщения, которые принимались слишком долго (поскольку процесс, который их принимал, вероятно, потерпел крах).

Это слишком много хлопот, есть некоторые сторонние почтовые запросы, такие как Mail_Queue PEAR.