Ruby on rails - ActiveRecord::lock 引发的异常类型



我在我的代码中使用了lock!,并希望捕获如果lock!由于某种原因(例如无法获得锁定(而引发的异常。什么样的例外可以锁定!扔?我检查了 ruby 文档,但找不到特定的异常类。

谢谢。

如有疑问,请进行探测。

请考虑以下一对函数:

def long_hold
  ActiveRecord::Base.transaction do
    u = User.find(220)
    u.lock!
    sleep 100.seconds
    u.email="foo@bar.com"
    u.save!
  end
end
def short_hold
  ActiveRecord::Base.transaction do
    u = User.find(220)
    u.lock!
    u.email="foo@bar.com"
    u.save!
  end
end

在我的设置(OSX 10.11,ruby 2.2.4,rails 4.2,postgres 9.5(中,在一个rails控制台中运行long_hold,然后在另一个控制台中运行short_hold,我观察short_hold块,直到long_hold完成;此外,使用puts检测代码,我们看到当long_hold处于睡眠状态时,short_hold正在等待获取锁。

假设没有关于 rails 控制台独立性的警告,这表明如果第二个进程尝试锁定已锁定的行,但该进程会阻塞直到第一个进程完成,则不会引发异常。

这是该锁定调用的来源。它调用重新加载,其源如下所示:

          # File lib/active_record/base.rb, line 2333
2333:       def reload(options = nil)
2334:         clear_aggregation_cache
2335:         clear_association_cache
2336:         @attributes.update(self.class.find(self.id, options).instance_variable_get('@attributes'))
2337:         @attributes_cache = {}
2338:         self
2339:       end

因此,当您调用 reload(:lock => lock( 作为对 lock 的调用时,它确实会更新该记录的属性。

这里有很多不同的情况。您可以尝试锁定存在 dosnt 的记录,或锁定已在其他地方锁定的记录。你有兴趣捕捉什么错误?

最新更新