ActiveRecord 中的悲观锁什么时候释放?

发布于 2024-09-09 03:59:02 字数 533 浏览 2 评论 0原文

假设我正在做类似的事情(来自活动记录查询指南< /a>)

Item.transaction do  
  i = Item.first(lock: true)  
  i.name = 'Jones'  
  i.save 
end 

事务结束时锁是否自动释放?我查看了 Active Query 指南和 ActiveRecord::Locking::Pessimistic docs,并且找不到明确说明锁释放位置的位置。

Assuming I'm doing something like this (from the Active Record Querying guide)

Item.transaction do  
  i = Item.first(lock: true)  
  i.name = 'Jones'  
  i.save 
end 

Is the lock automatically released at the end of the transaction? I've looked at the Active Query guide and the ActiveRecord::Locking::Pessimistic docs, and couldn't find where it explicitly says where the lock is released.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

红颜悴 2024-09-16 03:59:02

锁定不是rails的功能,它只是将锁定语句添加到查询中,这会根据您使用的数据库而有所不同。悲观锁定采取“悲观”观点,认为每个查询都会受到损坏。因此,它将锁定选定的行,直到您完成事务。所以锁定>查询>开锁。虽然这些数据库与数据库之间相当一致,但最好阅读您使用的数据库文档来了解您应该了解的任何特定于数据库的内容。

这是一个关于乐观锁定与悲观锁定的好帖子,它比我能更好地解释它。 乐观锁定与悲观锁定

Locking is not a function of rails, it is just adding the lock statement to the query, which will vary depending on the database that you are using. Pessimistic Locking takes a "pessimistic" view in thinking that every query is subject to corruption. So it is going to lock selected rows until you are finished with the transaction. so Lock > query > unlock. While these are fairly consistent database to database, it might be good to read up on the database documentation that you using for any database-specific things you should know.

Here is a good thread on optimistic vs. pessimistic locking that explains it better than I can. Optimistic vs. Pessimistic locking

你对谁都笑 2024-09-16 03:59:02

是的,锁在事务结束时自动释放,因为这种锁只适用于事务。在事务之外以这种方式锁定记录(悲观锁)是没有意义的。

悲观锁在数据库级别强制执行。

下面是 mysql 的示例说明:
http://dev.mysql.com/doc/refman /5.0/en/innodb-lock-modes.html

Yes, the lock automatically released at the end of the transaction because this kind of lock is applicable to transactions only. It does not make sense to lock the record this way (pessimistic lock) outside the transaction.

Pessimistic locks are enforced on DB level.

Below is a description with examples for mysql:
http://dev.mysql.com/doc/refman/5.0/en/innodb-lock-modes.html

纸短情长 2024-09-16 03:59:02

我承认在 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 "updates with lock" do
  Foobar.foo
  expect(model.reload.bar).to eq("baz")
end

I acknowledged the problem with pessimistic lock within transaction during rspec tests.
For some reason on different systems (I found this because of CI failed to run spec) record is still locked and cannot be fetched.

So code and rspec example are below.

class FooBar
  def foo
    Model.with_lock do
      model.update(bar: "baz")
    end
  end
end

red example

it "updates with lock" do
  expect { Foobar.foo }.to change { model.reload.bar }.to("baz")
end

but correct green example should look like this

it "updates with lock" do
  Foobar.foo
  expect(model.reload.bar).to eq("baz")
end
呆萌少年 2024-09-16 03:59:02

我相信您会需要一个“确保”块来确定锁已释放。

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/ 似乎表明该方法的块结构将自动解锁。

I believe you'll want an "ensure" block to be certain the lock is released.

http://ruby-doc.org/core/classes/Mutex.src/M000916.html has:

  def synchronize
    lock
    begin
      yield
    ensure
      unlock
    end
  end

http://yehudakatz.com/2010/02/07/the-building-blocks-of-ruby/ seems to suggest, however, that the block structure of that method will automatically unlock.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文