Rails执行作业时ActiveJob SQS和记录仍然不存在
Rails ActiveJob SQS and record still not exists when executing the Job
我正在使用 SQS 作为我的 ActiveJobs 的后端。
我有一个非常简单的作业,它在我的模型的 after_create
回调中发送到队列:
after_create :update_stuff_after_create
这会初始化一个 ActiveJob:
UpdateStuffAfterCreateJob.perform_later(self.id)
作业被正确发送到SQS队列。问题是,当 另一个负责从队列中读取的实例 试图执行作业时,我看到 ActiveRecord::RecordNotFound
:
class UpdateStuffAfterCreateJob < ActiveJob::Base
def perform(id)
publisher_offer_click = MyModel.find(id) # ActiveRecord::RecordNotFound
my_model.update_stuff
end
end
看起来记录存在于发送作业的实例中,但记录不存在于使用作业的实例中。
我一直在深入调试并创建了这个作业:
class TestingEntityExistsJob < ActiveJob::Base
def perform(id, exists_outside, time_outside_string)
Rails.logger.info "[TestingEntityExistsJob] #{id}, #{MyModel.last.id}, #{Time.now.strftime("%H:%M:%S.%L")}, #{time_outside_string}, exists: #{MyModel.where(:id => publisher_offer_click_id).exists?}, exists_outside: #{exists_outside}"
end
end
我在模型的 after_create
中这样称呼它:
TestingEntityExistsJob.perform_later(self.id, MyModel.where(:id => self.id).exists?, Time.now.strftime('%H:%M:%S.%L'))
我有这样奇怪的结果:
[2017-05-05 16:13:12.773] [TestingEntityExistsJob] 30645284, 30645284, 16:13:12.781, 16:13:12.720, exists: true, exists_outside: true
[2017-05-05 16:13:12.773] [TestingEntityExistsJob] 30645281, 30645284, 16:13:12.781, 16:13:12.659, exists: true, exists_outside: true
[2017-05-05 16:13:12.913] [TestingEntityExistsJob] 30645283, 30645284, 16:13:12.929, 16:13:12.838, exists: true, exists_outside: true
[2017-05-05 16:13:12.964] [TestingEntityExistsJob] 30645285, 30645285, 16:13:12.970, 16:13:12.927, exists: true, exists_outside: true
[2017-05-05 16:13:13.368] [TestingEntityExistsJob] 30645286, 30645285, 16:13:13.391, 16:13:13.309, exists: false, exists_outside: true
[2017-05-05 16:13:13.374] [TestingEntityExistsJob] 30645287, 30645285, 16:13:13.391, 16:13:13.339, exists: false, exists_outside: true
[2017-05-05 16:13:13.447] [TestingEntityExistsJob] 30645288, 30645288, 16:13:13.453, 16:13:13.411, exists: true, exists_outside: true
[2017-05-05 16:13:13.718] [TestingEntityExistsJob] 30645289, 30645289, 16:13:13.723, 16:13:13.658, exists: true, exists_outside: true
[2017-05-05 16:13:14.702] [TestingEntityExistsJob] 30645290, 30645290, 16:13:14.722, 16:13:14.642, exists: true, exists_outside: true
[2017-05-05 16:13:14.842] [TestingEntityExistsJob] 30645291, 30645291, 16:13:14.850, 16:13:14.789, exists: true, exists_outside: true
[2017-05-05 16:13:17.658] [TestingEntityExistsJob] 30645292, 30645292, 16:13:17.663, 16:13:17.599, exists: true, exists_outside: true
[2017-05-05 16:13:18.558] [TestingEntityExistsJob] 30645294, 30645294, 16:13:18.565, 16:13:18.513, exists: true, exists_outside: true
[2017-05-05 16:13:18.648] [TestingEntityExistsJob] 30645293, 30645294, 16:13:18.652, 16:13:18.592, exists: false, exists_outside: true
[2017-05-05 16:13:19.565] [TestingEntityExistsJob] 30645295, 30645295, 16:13:19.570, 16:13:19.514, exists: true, exists_outside: true
[2017-05-05 16:13:21.899] [TestingEntityExistsJob] 30645296, 30645295, 16:13:21.918, 16:13:21.771, exists: false, exists_outside: true
[2017-05-05 16:13:21.916] [TestingEntityExistsJob] 30645297, 30645295, 16:13:21.923, 16:13:21.832, exists: false, exists_outside: true
[2017-05-05 16:13:22.541] [TestingEntityExistsJob] 30645298, 30645298, 16:13:22.547, 16:13:22.484, exists: true, exists_outside: true
[2017-05-05 16:13:23.223] [TestingEntityExistsJob] 30645299, 30645299, 16:13:23.228, 16:13:23.171, exists: true, exists_outside: true
您总是 exists
从外部看到记录,但并不总是在作业执行的内部。有时 MyModel.last.id
小于我要加载的记录的 id
。
关于为什么会发生这种情况有什么建议吗?我做错了什么?
此行为的原因是 after_create
在提交 save
的事务时触发。这会导致有一段短暂的时间,在此期间作业的数据库连接无法访问记录,因为模型的数据库连接尚未提交。
您需要使用
after_commit :some_method, on: [:create]
而不是
after_create :some_method
https://apidock.com/rails/ActiveRecord/Transactions/ClassMethods/after_commit
我正在使用 SQS 作为我的 ActiveJobs 的后端。
我有一个非常简单的作业,它在我的模型的 after_create
回调中发送到队列:
after_create :update_stuff_after_create
这会初始化一个 ActiveJob:
UpdateStuffAfterCreateJob.perform_later(self.id)
作业被正确发送到SQS队列。问题是,当 另一个负责从队列中读取的实例 试图执行作业时,我看到 ActiveRecord::RecordNotFound
:
class UpdateStuffAfterCreateJob < ActiveJob::Base
def perform(id)
publisher_offer_click = MyModel.find(id) # ActiveRecord::RecordNotFound
my_model.update_stuff
end
end
看起来记录存在于发送作业的实例中,但记录不存在于使用作业的实例中。
我一直在深入调试并创建了这个作业:
class TestingEntityExistsJob < ActiveJob::Base
def perform(id, exists_outside, time_outside_string)
Rails.logger.info "[TestingEntityExistsJob] #{id}, #{MyModel.last.id}, #{Time.now.strftime("%H:%M:%S.%L")}, #{time_outside_string}, exists: #{MyModel.where(:id => publisher_offer_click_id).exists?}, exists_outside: #{exists_outside}"
end
end
我在模型的 after_create
中这样称呼它:
TestingEntityExistsJob.perform_later(self.id, MyModel.where(:id => self.id).exists?, Time.now.strftime('%H:%M:%S.%L'))
我有这样奇怪的结果:
[2017-05-05 16:13:12.773] [TestingEntityExistsJob] 30645284, 30645284, 16:13:12.781, 16:13:12.720, exists: true, exists_outside: true
[2017-05-05 16:13:12.773] [TestingEntityExistsJob] 30645281, 30645284, 16:13:12.781, 16:13:12.659, exists: true, exists_outside: true
[2017-05-05 16:13:12.913] [TestingEntityExistsJob] 30645283, 30645284, 16:13:12.929, 16:13:12.838, exists: true, exists_outside: true
[2017-05-05 16:13:12.964] [TestingEntityExistsJob] 30645285, 30645285, 16:13:12.970, 16:13:12.927, exists: true, exists_outside: true
[2017-05-05 16:13:13.368] [TestingEntityExistsJob] 30645286, 30645285, 16:13:13.391, 16:13:13.309, exists: false, exists_outside: true
[2017-05-05 16:13:13.374] [TestingEntityExistsJob] 30645287, 30645285, 16:13:13.391, 16:13:13.339, exists: false, exists_outside: true
[2017-05-05 16:13:13.447] [TestingEntityExistsJob] 30645288, 30645288, 16:13:13.453, 16:13:13.411, exists: true, exists_outside: true
[2017-05-05 16:13:13.718] [TestingEntityExistsJob] 30645289, 30645289, 16:13:13.723, 16:13:13.658, exists: true, exists_outside: true
[2017-05-05 16:13:14.702] [TestingEntityExistsJob] 30645290, 30645290, 16:13:14.722, 16:13:14.642, exists: true, exists_outside: true
[2017-05-05 16:13:14.842] [TestingEntityExistsJob] 30645291, 30645291, 16:13:14.850, 16:13:14.789, exists: true, exists_outside: true
[2017-05-05 16:13:17.658] [TestingEntityExistsJob] 30645292, 30645292, 16:13:17.663, 16:13:17.599, exists: true, exists_outside: true
[2017-05-05 16:13:18.558] [TestingEntityExistsJob] 30645294, 30645294, 16:13:18.565, 16:13:18.513, exists: true, exists_outside: true
[2017-05-05 16:13:18.648] [TestingEntityExistsJob] 30645293, 30645294, 16:13:18.652, 16:13:18.592, exists: false, exists_outside: true
[2017-05-05 16:13:19.565] [TestingEntityExistsJob] 30645295, 30645295, 16:13:19.570, 16:13:19.514, exists: true, exists_outside: true
[2017-05-05 16:13:21.899] [TestingEntityExistsJob] 30645296, 30645295, 16:13:21.918, 16:13:21.771, exists: false, exists_outside: true
[2017-05-05 16:13:21.916] [TestingEntityExistsJob] 30645297, 30645295, 16:13:21.923, 16:13:21.832, exists: false, exists_outside: true
[2017-05-05 16:13:22.541] [TestingEntityExistsJob] 30645298, 30645298, 16:13:22.547, 16:13:22.484, exists: true, exists_outside: true
[2017-05-05 16:13:23.223] [TestingEntityExistsJob] 30645299, 30645299, 16:13:23.228, 16:13:23.171, exists: true, exists_outside: true
您总是 exists
从外部看到记录,但并不总是在作业执行的内部。有时 MyModel.last.id
小于我要加载的记录的 id
。
关于为什么会发生这种情况有什么建议吗?我做错了什么?
此行为的原因是 after_create
在提交 save
的事务时触发。这会导致有一段短暂的时间,在此期间作业的数据库连接无法访问记录,因为模型的数据库连接尚未提交。
您需要使用
after_commit :some_method, on: [:create]
而不是
after_create :some_method
https://apidock.com/rails/ActiveRecord/Transactions/ClassMethods/after_commit