我正在使用锁!在我的代码中,并希望捕获锁定时抛出的异常!由于某种原因失败(例如无法获得锁定)。什么样的例外可以锁定!扔?我检查了ruby文档,但找不到具体的Exception类。
感谢。
答案 0 :(得分:2)
如有疑问,请进行探测。
考虑以下一对功能:
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
,我观察{{1阻止short_hold
完成;此外,使用puts来检测代码,我们看到当long_hold
正在休眠时,long_hold
正在等待获取锁。
假设没有关于rails控制台独立性的任何警告,这表明如果第二个进程试图锁定已经锁定的行,则不会抛出任何异常,但该进程将阻塞直到第一个完成。
答案 1 :(得分:1)
以下是locking call的来源。它调用reload,它的源代码如下:
# 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存在的记录,或锁定已在其他位置锁定的记录。你有兴趣捕捉到什么错误?