我在创建记录后使用sidekiq来运行一些工作。当作业尝试查找具有创建的ID的记录时,会有随机的情况,它会引发RecordNotFound
。怎么可能呢?
class Person
def self.test_create
p = Person.create(
name: 'test'
)
p.run_on_sidekiq
end
def run_on_sidekiq
PersonJob.perform_async(self.id)
end
end
# Sidekiq runs on other server.
class PersonJob
def perform(id)
person = Person.find(id) # sometimes raises RecordNotFound!
# ...
# do something
# ...
end
end
编辑:根据Alexei的回答,这个案例与Sidekiq更相关。编辑了问题以添加关于Sidekiq用法的更多细节。
答案 0 :(得分:1)
create
并不保证如果有任何错误,它也会以静默方式回滚。
create!
会因失败而提出exception
。
我认为调用方法的理想方法是检查对象是否为persisted?
对数据库。
def test_create
person = Person.create(name: 'test')
person.some_method if person.persisted?
end
其他方式:
person.some_method unless person.errors.any?
答案 1 :(得分:1)
这是您using Sidekiq in after_create
挂钩的常见情况。实际上是Sidekiq在交易完成之前开始工作,这就是为什么它无法在数据库中找到模型(也因为它的速度非常快)。您需要做的是将after_create
挂钩更改为after_commit
,以确保交易已完成。
如果您显示使用Sidekiq的确切代码,我可以详细说明您的具体用法。
更新:
这很奇怪,您的当前代码应该没问题,因为在事务中调用save/destroy
已经gets wrapped。
我能想到的一个原因是验证错误。如果您的Person.create
来电以某种方式失败,那么您将获得Person
id
nil
id=nil
的实例。这样,Sidekiq将尝试使用NSLayoutConstraint
查找记录,并将抛出错误。