을 감안할 때 사용자 및 트랜잭션 모델 : I 사용자를 업데이트하는 경쟁 조건을 가지고잠재적 경쟁 조건이 4 개
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
첫째 :
class User < ActiveRecord::Base
has_many :transactions
end
class Transaction < ActiveRecord::Base
belongs_to :user
end
문제는 너무 자주라는 API로 발생 단지 @data.user
을 사용하여 균형을 잡으십시오. 때로는 이전에 새로운 요청이 끝났기 때문에 일부 데이터가 손실되었습니다. 대신 그 사용자에 대한 잠금을 요청하기 시작했습니다.
다음 경쟁 조건은 총 트랜잭션 수를 세는 것과 같았습니다. 이제 알 수 있듯이 inform_user에 다른 RC가 있습니다.
그래서 내가 잘못한 점은 무엇입니까?
inform_user.with_lock do
inform_user.balance = inform_user.aff_balance.to_f + @amount.to_f
end
그리고 또 다른 질문, 그것은 부모를 업데이트하는 동안 나는 관계 모델을 업데이트해야 할 때, 예를 들어 중첩 잠금을 사용하는 좋은 방법이다 : 그것은과 inform_user의 업데이트 균형을 다시 할 수있는 좋은 방법이 있나요?
http://api.rubyonrails.org/classes/ActiveRecord/CounterCache/ClassMethods.html#method-i-update_counters
레일 API는 복잡한 모델과 함께 작동하지 않는 간단한 트랜잭션을 사용하여 제시하기 때문에, 그것은 좋은 대신 Model.transaction의 사용자 잔액을 업데이트하는 update_counters을 사용하는 것입니다,이 조언을 주셔서 감사합니다. 또한 모델을 만들거나 업데이트 할 때 모델을 잠그는 가장 좋은 방법은 무엇입니까? – nateless