在 ruby v 2.1.3 中设置隔离级别

Setting Isolation level in ruby v 2.1.3

我一直在努力在我的 table 上设置记录级别锁,以避免在更新记录时出现任何脏读和竞争条件。 我正在使用 ruby 2.1.3 和 rails 版本 3.2.13。我尝试使用命令:

Account.connection.execute("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE")

并通过睡眠进行了测试,但是 2 个进程试图更新同一条记录读取旧值并且最终数据是错误的。例如:如果我的旧值是 100,则两个进程都读取 100 然后更新 100+x 和 100+y,因此数据已损坏。

我正在使用 mySQL 数据库。感谢任何帮助。

Rails支持两种锁定机制:optimistic and pessimistic

更新账户余额,使用悲观锁定,应该是这样的:

acc = Account.find(id)
acc.with_lock do
  acc.balance += 100
  acc.save!
end

以下解决方案对我有用(对 dimakura 的回答稍作修改):

  1. 当我使用 find() 进行活动记录查询时:

    acc = Account.lock.find(id)
    acc.balance += 100
    acc.save!
    
  2. 当我使用 where() 进行活动记录查询时:

    acc = Account.where(:acc_code => acc_code).first
    acc.with_lock do
     acc.balance += 100
     acc.save!
    end