双重执行代码

时间:2015-07-16 13:57:02

标签: ruby-on-rails ruby

我使用Ruby 2.0.0运行Rails 4.2.0。我遍历模型Production.all并在.each循环中调用production.finish!。 我的完成!方法,最后,用self.destroy删除自己。但是每个未定义的条目将在同一个循环中执行两次。

def finish!
  self.progress = true
  self.save # that other crontabs can't access me anymore if the crontabs overlap

  if DeliveredProduction.find_by_production_id(self.id)
    # send me a notification, why this object still exists?
  else
    DeliveredProduction.create!(:production_id => self.id) # Each undefined times a get an Exception here because the production_id is already insert!
    # ...
    # do things here
  end
  self.destroy # my debug logs says that each entry was successful deleted
end

Rails 4.2.0或Ruby 2.2.0p0中是否有Bug?它只发生在1-2天之后才能执行一次。该代码将由crontab执行。我还使用progress = true更新迭代中的所有Production,以便以后的crontabs无法访问此对象。我的调试日志表明,同一个Production的第二次执行是在几秒钟后的同一时间(相同的秒)。

1 个答案:

答案 0 :(得分:0)

你应该使用after_commit回调来做这些事情:

after_commit :deliver!, on: :update, if: ->{|me| me.progress}

def finish!
  self.update(progress: true)
end

def deliver!
  DeliveredProduction.create!(:production_id => self.id)
  self.destroy
end

Model#save并不保证在执行下一行代码时会保存记录。 after_commit。只需了解after_commit的注意事项:

Rails documentation on 'after_commit'