Поставете транзакция около двете заявки и използвайте FOR UPDATE
опция в SELECT
заявка за заключване на редовете, които е прегледал. Всяка друга връзка, която се опитва да прочете този ред, ще бъде спряна, докато транзакцията не бъде завършена.
Уверете се, че имате индекс на колоните, които тествате в WHERE
клауза, така че няма да се налага да прави сканиране и да заключва всички редове, които е проверил, преди да намери този, който искате.
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;