假设我正在做这样的事情(来自Active Record Querying guide)
Item.transaction do
i = Item.first(:lock => true)
i.name = 'Jones'
i.save
end
在交易结束时锁是否自动释放?我查看了“活动查询”指南和ActiveRecord::Locking::Pessimistic docs,但无法找到明确说明锁定释放位置的位置。
答案 0 :(得分:24)
锁定不是rails的功能,它只是将lock语句添加到查询中,这将根据您使用的数据库而有所不同。 Pessimistic Locking认为每个查询都会受到腐败,因此采取“悲观”的观点。因此,在您完成事务之前,它将锁定所选行。所以锁定>查询>开锁。虽然这些数据库与数据库是相当一致的,但是阅读您用于任何您应该知道的特定于数据库的事物的数据库文档可能会很好。
这是一个关于乐观与悲观锁定的好线程,它比我能更好地解释它。 Optimistic vs. Pessimistic locking
答案 1 :(得分:5)
是的,锁在交易结束时自动释放,因为这种锁只适用于交易。在事务之外以这种方式锁定记录(悲观锁定)是没有意义的。
在数据库级别强制执行悲观锁定。
以下是mysql示例的说明: http://dev.mysql.com/doc/refman/5.0/en/innodb-lock-modes.html
答案 2 :(得分:0)
我承认在rspec测试期间事务内的悲观锁定问题。 出于某种原因,在不同的系统上(我发现这是由于CI无法运行规范),记录仍然被锁定并且无法获取。
下面是代码和rspec示例。
class FooBar
def foo
Model.with_lock do
model.update(bar: "baz")
end
end
end
红色示例
it "updates with lock" do
expect { Foobar.foo }.to change { model.reload.bar }.to("baz")
end
但正确 绿色示例应如下图所示
it do "updates with lock" do
Foobar.foo
expect(model.reload.bar).to eq("baz")
end
答案 3 :(得分:-2)
我相信你会想要一个“确保”阻止来确定释放锁定。
http://ruby-doc.org/core/classes/Mutex.src/M000916.html有:
def synchronize
lock
begin
yield
ensure
unlock
end
end
然而,http://yehudakatz.com/2010/02/07/the-building-blocks-of-ruby/似乎暗示该方法的块结构将自动解锁。