この問題は「競合状態」と呼ばれます。この場合、SELECT と UPDATE は次々に呼び出されますが、単一の操作ではないために発生します。したがって、2 つのジョブが同じジョブを SELECT し、次に最初に UPDATE を実行し、次に 2 番目に UPDATE を実行する可能性があります。そして、彼らはこの仕事を同時に実行し始めます。
ただし、回避策があります。現在の cron ジョブ ワーカーの ID を含むフィールドをテーブルに追加できます (1 台のマシンですべてを実行する場合は、PID である可能性があります)。ワーカーでは、最初に UPDATE を実行し、ジョブを予約しようとします。
UPDATE jobs
SET worker = $PID, status = 'processing'
WHERE worker IS NULL AND status = 'awaiting' LIMIT 1
次に、このワーカーのジョブが正常に予約されたことを確認します。
SELECT * FROM jobs WHERE worker = $PID
行が返されなかった場合は、他のワーカーが最初にそれを予約したことを意味します。ステップ 1 からやり直して、別のジョブを取得できます。行が返された場合は、すべての処理を行い、最後に最終的な UPDATE を行います。
UPDATE jobs
SET status = 'done', worker = NULL
WHERE id = $JOB_ID