【发布时间】:2014-01-23 18:46:24
【问题描述】:
我想知道如何处理给定总账的并发性。考虑这样的架构:
id | account_id | credit | debit | balance |
1 | 123 | 0 | 100 | 200 |
2 | 456 | 100 | 0 | 100 |
要向分类帐添加新条目,我会这样做(伪代码):
last_entry = get last account entry
is_credit = figure out if it is debit or credit entry
is_liability = figure out type of account
new_entry = Entry(
foo='bar'
# etc
)
if is_liability and is_credit
new_entry.balance = last_entry.balance + amount
if is_liability and !is_credit
new_entry.balance = last_entry.balance - amount
if !is_liability and is_credit
new_entry.balance = last_entry.balance - amount
if !is_liability and !is_credit
new_entry.balance = last_entry.balance + amount
new_entry.save()
我看到这种方法的问题是:
假设有一个请求来了,我必须在分类帐中输入新条目。新条目将增加帐户余额。
如果在运行上述代码的过程中(假设在获得最后一个条目之后)有另一个请求会再次增加余额。
所以余额将增加一次,另一个请求将保存一个具有相同余额的新条目,因为它将使用类似的内容:
new_balance = last_entry.balance + amount
但是 last_entry 已经被另一个请求过期了,所以现在余额更高了。
关于如何确保不会发生这种情况的任何想法(我知道这不太可能)。
更新:
根据一些答案,我使用 SELECT FOR UPDATE 提出了这个解决方案:
with transaction.atomic():
new_entries = prepare_entries()
for new_entry in new_entries:
new_entry.save()
这是解决潜在并发问题的好方法吗?
【问题讨论】:
标签: python sql django concurrency