2つのクエリの周りにトランザクションを配置し、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;