在 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 的回答稍作修改):
当我使用 find() 进行活动记录查询时:
acc = Account.lock.find(id)
acc.balance += 100
acc.save!
当我使用 where() 进行活动记录查询时:
acc = Account.where(:acc_code => acc_code).first
acc.with_lock do
acc.balance += 100
acc.save!
end
我一直在努力在我的 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 的回答稍作修改):
当我使用 find() 进行活动记录查询时:
acc = Account.lock.find(id) acc.balance += 100 acc.save!
当我使用 where() 进行活动记录查询时:
acc = Account.where(:acc_code => acc_code).first acc.with_lock do acc.balance += 100 acc.save! end