我正在尝试使用Sidekiq工作人员执行一些后台任务。
Sidekiq 真的强调让工作线程安全。工作人员基本上将使用#inc()
更新Mongoid文档,这是原子的(因此是线程安全的)。但在实际更新之前,他们还会执行Model.find_or_create_by
调用,这不是原子的(它等于单独的QUERY
和INSERT
操作)。
我是否正确地认为这可能会导致竞争条件 - 2名工人一起跑,将同时执行QUERY
(两者都会失败)然后执行INSERT
(这将成功一个但是另一个失败,因为我的模型具有唯一性条款的索引)
为了避免上述情况,我将find_or_create_by包装在begin-rescue子句中:
begin
x = A.find_or_create_by(...)
rescue
x = A.find_by(...)
end
这是正确的方法,还是有一种更简单的方法以线程安全的方式创建Mongoid文档?
编辑:我见过Is find_or_create_by thread safe in Mongoid?,但它没有给出解决方案,它只是确认find_create_by不是线程安全的。