3

这很简单,我正在运行一个查找 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。创建小部件时如何防止竞争条件,以免出现重复?

4

1 回答 1

1

因为唯一检查和插入是分开执行的,所以存在竞争条件。您需要一个索引来强制执行唯一性约束。

文档提到了这一点:http: //guides.rubyonrails.org/active_record_validations.html#uniqueness

于 2015-02-28T03:39:34.367 回答