0

为了更好地理解悲观锁定(使用 InnoDB),我尝试在我的 Rails 应用程序中运行这段代码:

Thread.new do
  Account.transaction do
    account = Account.lock(true).first
    account.balance += 250
    account.save!
  end
end

Thread.new do
  Account.transaction do
    account = Account.lock(true).first
    account.balance += 500
    account.save!
  end
end

它实际上有效,account.balance然后 contains 750,然后1500在下一次命中。没有锁定,它只考虑最后一个线程,结果是500.

这是一个愚蠢的测试来尝试锁定与否之间的区别吗?我我了解悲观锁定的原理,但不确定。

4

1 回答 1

1

该测试确实允许您观察悲观锁定行为,但是当您删除锁定时,它不会切换到乐观锁定。它根本没有锁定。

此外,为了更惯用,您可以这样做:

Thread.new do
  account = Account.first
  account.with_lock do
    account.balance += 250
    account.save!
  end
end

with_lock启动事务并一次性获得锁。

要观察乐观锁定行为,您需要lock_version在模型中存在字段。Rails 将自动进行记录版本检查并引发ActiveRecord::StaleObjectError冲突。

于 2016-06-30T11:18:09.477 回答