【问题标题】:DelayedJob breaking validates unique constraints in ActiveRecordDelayedJob 中断验证 ActiveRecord 中的唯一约束
【发布时间】:2015-02-28 11:39:34
【问题描述】:

这很简单,我正在运行一个查找 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 个内核上运行,这些作业在完全相同的时间运行,导致尽管进行了两项检查,仍会创建多个小部件。如何在创建小部件时防止出现竞争条件,以免出现重复?

【问题讨论】:

    标签: activerecord delayed-job race-condition


    【解决方案1】:

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

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

    【讨论】:

    • 数据库索引将解决创建重复记录的问题,但它们会引发错误,因为代码仍将同时运行并且只有数据库会阻止插入。我想要一个应用程序级别的解决方案,而不是数据库级别的解决方案。也许是 ActiveRecord 交易?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 2015-04-13
    • 2013-05-21
    • 2019-02-24
    • 2014-01-29
    • 2015-11-13
    • 1970-01-01
    相关资源
    最近更新 更多