Placez une transaction autour des deux requêtes et utilisez le FOR UPDATE
option dans le SELECT
requête pour verrouiller les lignes qu'elle a examinées. Toute autre connexion essayant de lire cette ligne sera suspendue jusqu'à ce que la transaction soit validée.
Assurez-vous d'avoir un index sur les colonnes que vous testez dans WHERE
clause, ainsi il n'aura pas à faire une analyse et à verrouiller toutes les lignes qu'il a vérifiées avant de trouver celle que vous voulez.
START TRANSACTION;
SELECT @id := `id`,`item`
FROM `queue_items`
WHERE `processed_at` IS NULL AND `completed_at` IS NULL
ORDER BY `id` ASC
LIMIT 1
FOR UPDATE;
UPDATE `queue_items` SET `processed_at` = @processedAt WHERE `id` = @id
COMMIT;