这很简单,我正在运行一个查找 Cogs 的爬虫。Cogs 可以属于一个单一的 Widget。有时它会找到一堆应该属于同一个 Widget 的 Cog。在 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")
这是不可避免的,但我认为会由上面的匹配代码处理。我在 Widget 模型中也有这个:
validates :name, presence: true, uniqueness: true
不幸的是,由于 4 个 DelayedJob 工作人员在 4 个内核上运行,这些作业同时运行,导致尽管进行了两项检查,仍会创建多个 Widget。创建小部件时如何防止竞争条件,以免出现重复?