UPDATE
行をロックするため、最初にロックする必要はありません。 UPDATE
しようとした場合 同時に重複する行のセット、2番目のUPDATE
最初のトランザクションがコミットまたはロールバックするのを待ちます。
あなたのアプローチの大きな問題-UPDATE
という事実以外 LIMIT
がありません 句-複数のワーカーがすべて同じ行を取得しようとすることです。何が起こるか:
- worker1:テーブルをフィルタリングして200行を検索し、それらをロックします
- worker1:行の更新を開始します
- worker2:テーブルをフィルタリングして200行を検索します
- worker2:行の更新を開始しようとしましたが、worker1と同じ行を選択したため、worker1のロックをブロックします
- worker1:行の更新を終了します
- worker2:ロックが解除された後、WHERE条件を再チェックし、worker1が行を更新したため、どの行も一致しなくなったことを確認します。ゼロ行を更新します。
...そして繰り返します!
次のいずれかを行う必要があります:
- 中央に
キュー を配置します 適切な並行性に安全な方法で行を配ります。または - 作業するIDの範囲が重複しないワーカーを割り当てます
LIMIT
について -WHERE id IN (SELECT t.id FROM thetable t LIMIT 200 ORDER BY id)
を使用できます -ただし、両方のワーカーが同じ行のセットを選択して更新する場合にも同じ問題が発生します。