私はあなたのために実用的な解決策を持っています。それは私の職場のプロジェクトで実行されているのを見たものです。不完全なものと完了したものに0と1だけを使用するのではなく、セットを拡張してさらに多くのケースを含めます。
その列をステータスと呼びましょう 。その列のさまざまな値と対応するジョブの状態を次に示します。
- ステータスが0の場合、ジョブはどのワーカースレッドによっても取得されていません。
- ステータスが1の場合、ジョブはワーカースレッドによって取得され、処理中です。
- ステータスが2の場合、ジョブは失敗しました。 (処理に失敗する可能性を考慮する必要があります。)
- ステータスが3の場合、ジョブは完了しています。
スレッドには、ステータスが0のジョブのみを取得し、ステータスを1に変更するようなロジックが含まれている必要があります。これにより、他のスレッドが処理中のジョブを取得できなくなります。ジョブが完了すると、ステータスは3に設定され、ジョブが失敗した場合、ステータスは2に設定されます。その後、スレッドは次に進み、まだ完了していない別のジョブを探すことができます。
ステータス2のジョブの取得を検討するようにスレッドに依頼することもできますが、有限の再試行回数を指定するロジックを定義する必要があります。
編集:
長いディスカッション の後 、私たちは一緒に解決策に出くわしました。上記の答えは、「ジョブ」が完了するまでに時間がかかるプロセスである場合に、より一般化された状態で適切です。しかし、OPの問題ではそうではありませんでした。
したがって、最終的に機能したソリューションは次のとおりです。
BEGIN
SELECT * FROM Jobs WHERE JobID = (SELECT * FROM Jobs WHERE completed = 0 LIMIT 1) LOCK IN SHARE MODE;
UPDATE Jobs SET completed = 1 WHERE JobID = (PREVIOUS ID);
COMMIT;