【发布时间】:2014-08-12 08:08:53
【问题描述】:
所以我有class Client 那个has_many :transactions。这两个字段都有货币化字段 (money-rails) gem。 INclass Transaction 我有after_create :add_customer_balance。它应该将此transaction.amount 添加到transaction.client 余额中。
我面临的问题是同时进行 2 笔交易的情况。我们来看看这种情况:
Variant 1:
time / process / code
0:01 / P1 / client = Client.find(1)
0:01 / P2 / client = Client.find(1)
0:02 / P1 / client.balance += 100
0:02 / P1 / client.save # SQL: update clients set balance = 200 where id = 1
0:03 / P2 / client.balance += 200
0:03 / P2 / client.save # SQL: update clients set balance = 300 where id = 1
Variant 2
to,e / process / code
0:01 / P1 / client = Client.find(1)
0:01 / P2 / client = Client.find(1)
0:02 / P1 / client.update_all(...) # SQL: update clients set balance = balance + 100 where id = 1
0:03 / P2 / client.update_all(...) # SQL: update clients set balance = balance + 200 where id = 1
Result:
Client.find(1).balance = 400
我的问题是:如何预防第一种情况?
我正在寻找可以增加平衡字段并立即将其保存到数据库的解决方案。
编辑
我尝试过increment!,但它似乎并不能阻止竞争条件。
def increment!(attribute, by = 1)
increment(attribute, by).update_attribute(attribute, self[attribute])
end
【问题讨论】:
标签: sql ruby-on-rails ruby activerecord ruby-on-rails-4