MySQL テーブルに対して同時に読み書きできるワーカーが複数あるとします (例: jobs
)。各ワーカーのタスクは次のとおりです:
キューに入れられた
ジョブ RUNNING
ワーカーがステップ #1 を実行するとき、適格なジョブが 存在しない可能性があることに注意してください (つまり、QUEUED)。
ROLLBACK) トランザクションをキャンセルする必要があると思います。以下のコードでこれを行うにはどうすればよいでしょうか?
ああああ
P粉5369091862023-12-22 09:14:00
あなたが何を望んでいるのかは明確ではありません。しかし、あなたのタスクが次の QUEUED
ジョブを見つけることであるとします。ステータスを RUNNING
に設定し、適切な ID を選択します。
シングルスレッド環境では、コードをそのまま使用できます。選択した ID をアプリケーション コードの変数に抽出し、WHERE 句の UPDATE クエリに渡します。 write ステートメントは 1 つだけなので、トランザクションも必要ありません。これを SQLscript で真似ることができます。
これがあなたの現在のステータスであると仮定します:
リーリー次のキューに入れられたジョブ (id=2) を開始したいと考えています。
リーリーあなたは得ます
リーリー最後の選択から開始します。テーブルのステータスは次のようになります:
リーリー ジョブを起動するプロセスが複数ある場合は、FOR UPDATE
を使用して行をロックする必要があります。ただし、LAST_INSERT_ID()
を使用すると、この状況を回避できます。
リーリー
次のものが得られます:リーリー
新しいステータスは次のとおりです:リーリー
UPDATE ステートメントがどの行にも影響を与えなかった (キューに入れられた行がない) 場合、ROW_COUNT() は
0 になります。
jobs テーブルに保存したいと考えています。簡単な例:
リーリー
###そして###
リーリー
を使用するだけで選択できます。 リーリー
もっと知りたいかもしれません - 例:queued_at
、started_at、
finished_at。
P粉6355097192023-12-22 00:24:50
今週、私はあなたのケースと非常によく似たものを実装します。複数のワーカー。それぞれが一連の行の「次の行」を取得して作業します。
疑似コードは次のとおりです:
リーリーFOR UPDATE
を使用することは、競合状態 (つまり、複数のワーカーが同じ行を取得しようとすること) を回避するために重要です。
SELECT ... INTO の詳細については、https://dev.mysql.com/doc/refman/8.0/en/select-into.html を参照してください。