これは非常に簡単です。私は歯車を見つけるクローラーを実行しています。コグは単一のウィジェットに属することができます。時々、すべてが同じウィジェットに属するべきであるたくさんの歯車を見つけます。Cogモデルでは、次のように実行されます。
# Find or create widget
match = Widget.where("name ILIKE (?)", name).first
match = Widget.create(name: name) unless match
すべてを並行して実行する遅延ジョブは、基本的に次のようになります。
- CREATE Cog, name: "cog1", (Widget, name: "Foo")
- CREATE Cog, name: "cog2", (Widget, name: "Foo")
- CREATE Cog, name: "cog3", (Widget, name: "Foo")
- CREATE Cog, name: "cog4", (Widget, name: "Foo")
これは避けられませんが、上記のマッチコードで処理できると思いました。ウィジェットモデルにもこれがあります:
validates :name, presence: true, uniqueness: true
残念ながら、4つのコアで4つのDelayedJobワーカーが実行されているため、これらのジョブはまったく同時に実行されるため、両方のチェックにもかかわらず、複数のウィジェットが作成されます。ウィジェットを作成するときに競合状態を防ぎ、重複しないようにするにはどうすればよいですか?