【发布时间】:2014-01-01 22:22:22
【问题描述】:
Rails 4.0.2、Mongoid git alpha、sidekiq 2.17.0
使用 worker 解析 CSV 文件并将内容放入 mongo,但遇到了几个问题……最明显的是,使用 find_or_create_by 时,同名产品最终会成为重复文档。
class Category
include Mongoid::Document
field :title, type: String
has_many :products
end
Class Product
include Mongoid::Document
field :name, type: String
belongs_to: :category
end
Class ProductWorker
include Sidekiq::Worker
def perform(category, name)
category = Category.find_or_create_by( title: category )
product = Product.find_or_create_by(name: name)
product.category = category
product.save
end
end
如果 CSV 文件中只有两个产品属于同一类别,我最终会得到两个具有相同名称的类别条目,每个产品位于不同的类别中。当我删除 sidekiq async 并直接在模型上执行它时,我得到了 1 个类别和两个关系产品的正确结果。
如果工作人员足够快地执行find_and_create_by,那么两个工作人员都会找到 nil 并因此创建新对象,这是有道理的。我怎样才能防止这种情况发生?
【问题讨论】:
-
还要注意,我是从应用程序的 postgresql 版本转换而来的。 postgresql 版本正确执行了带有重复字段的异步 CSV 导入。
-
唯一性验证在这里可以解决吗?
-
我开始验证唯一的类别名称,但是我删除了它,因为它在第一个产品上以
category_id: nil结尾,第二个产品是正确的 -
将 sidekiq 限制为只有 1 个工作人员似乎可以解决问题,尽管它不太理想......
-
我可以建议看看一些锁定 gem,例如 github.com/afeld/mongoid-locker 或 github.com/burgalon/mongoid_optimistic_locking。如果您能找到解决方案,请告诉我们。
标签: ruby-on-rails-4 mongoid sidekiq