使用Django ORM避免竞争条件的最佳方法是什么?我正在使用Postgres数据库。以下是易受竞争条件影响的代码的简化版本(很少但可能发生):
last_account_balance = AccountBalance.objects.filter(
account_id=account_id
).last()
new_account_balance = AccountBalance(
account_id=account_id,
balance= last_account_balance.balance + 100
)
new_account_balance.save()
如果两个单独的处理同时执行上面的代码怎么办?
假设使用account_id 123的数据库中的最后一个条目的余额为100。
第一个进程将插入一个平衡增加100的新条目,即200。
第二个流程将插入一个新的条目,余额增加100,即200。
但它应该从200增加到300,因为另一个进程在此期间插入了一个新行。
答案 0 :(得分:0)
我不认为你所描述的是一个很好的方法来解决你的问题。我要做的是,我要创建一个Deposit
模型,该模型对帐户有ForeignKey
并保存存款的日期和存入的金额(可能还需要其他信息) )。
现在,我只需添加一个新的Deposit
,然后每次只需将所有相关的Deposit
相加(并类似地减去Withdrawal
,我就可以获得该帐户的余额或多个)。
当然可能有其他用例实际上需要表锁定以确保表中的行不会在SQL语句之间发生更改,但这些是特定于数据库的并且与django无关。为了完整起见,我在这里找到了对postgresql表锁定的一个非常好的介绍http://www.postgresql.org/docs/9.1/static/explicit-locking.html - ACCESS EXCLUSIVE
表级锁定似乎解决了你的问题(不过我想到了在使用可能导致死锁的事情之前进行设计。)