Yeo*_*nho 5 ruby mysql ruby-on-rails sidekiq ruby-on-rails-4
创建记录后,我正在使用 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
Run Code Online (Sandbox Code Playgroud)
编辑:根据Alexei的回答,这个案例与 Sidekiq 更相关。编辑了问题以添加有关 Sidekiq 用法的更多详细信息。
当您在after_create钩子中使用 Sidekiq时,这是一种常见情况。实际发生的事情是 Sidekiq 在事务完成之前就开始工作,这就是为什么它在数据库中找不到模型的原因(也因为它非常快)。你需要做的是改变你的after_create钩子,after_commit以确保事务已经完成。
如果您显示使用 Sidekiq 的确切代码,我可以详细说明您的具体用法。
更新:这很奇怪,您当前的代码应该没问题,因为调用save/destroy已经包含在事务中。
我能想到的一个原因是验证错误。如果您的Person.create调用以某种方式失败,您将返回Personwhere idwould be的实例nil。这样,Sidekiq 将尝试查找记录id=nil并抛出错误。
create如果出现任何错误,也不保证它会默默地回滚。
create!会提出exception失败条件。
我认为调用方法的理想方法是检查对象是否persisted?针对数据库。
def test_create
person = Person.create(name: 'test')
person.some_method if person.persisted?
end
Run Code Online (Sandbox Code Playgroud)
另一种方式:
person.some_method unless person.errors.any?
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
989 次 |
| 最近记录: |