【发布时间】:2013-09-24 01:43:36
【问题描述】:
给定用户和交易模型:
class User < ActiveRecord::Base
has_many :transactions
end
class Transaction < ActiveRecord::Base
belongs_to :user
end
问题出现在 API 调用过于频繁:
def trx
User.transaction do
user = User.where(id: @data.user.id).lock(true).first
trx_number = user.transactions.count + 1
# some work
user.transactions.create(...)
change_balance = ...
user.balance = user.balance.to_f + change_balance.to_f
inform_user = user.has_valid_informee
if !result && inform_user
inform_user.balance = inform_user.aff_balance.to_f + @amount.to_f
inform_user.save!
end
user.save!
end
end
首先,我有一个竞争条件,仅使用 @data.user 更新用户余额,有时新请求在之前完成,因此我们丢失了一些数据。相反,我开始请求锁定该用户。
下一个竞争条件是计算总交易量,正如我现在看到的那样,我们将拥有另一个带有 inform_user 的 RC。
所以问题是我做错了吗?用以下方式重写inform_user的更新余额是否是一种好方法:
inform_user.with_lock do
inform_user.balance = inform_user.aff_balance.to_f + @amount.to_f
end
还有一个问题,它是使用嵌套锁的好方法吗,例如当我需要更新关系模型同时更新父模型时?
【问题讨论】:
标签: ruby-on-rails activerecord race-condition