我在我的代码中使用了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 的记录,或锁定已在其他地方锁定的记录。你有兴趣捕捉什么错误?