我想知道在一个总分类账下如何处理并发。考虑如下模式:
id | account_id | credit | debit | balance |
1 | 123 | 0 | 100 | 200 |
2 | 456 | 100 | 0 | 100 |
要在分类帐中添加一个新条目,我将执行以下操作(伪代码):
^{pr2}$我认为这种方法的问题是:
假设有一个请求来了,我必须在分类帐中输入新的分录。新的条目将增加帐户余额。在
如果在运行上述代码的过程中(比如在获得最后一个条目之后),有另一个请求将再次增加余额,那会怎样呢。在
因此余额将增加一次,另一个请求将用相同的余额保存一个新条目,因为它只会使用如下内容:
new_balance = last_entry.balance + amount
但最后一个_条目已被另一个请求过期,因此余额现在更高。在
有什么办法确保这种情况不会发生(我知道这不太可能)。在
更新:
根据一些答案,我使用SELECT FOR UPDATE想出了这个解决方案:
with transaction.atomic():
new_entries = prepare_entries()
for new_entry in new_entries:
new_entry.save()
这是解决潜在并发问题的好方法吗?在
计算将应用于
balance
的总差异并使用update
查询:{a1将返回一个事务^的锁,直到^结束为止:
或^{} 表达式:
例如:
^{pr2}$假设您的数据库支持它(为此,它应该支持),将整个操作包装在事务中。一、 e以“start transaction”调用开始,以commit结束。在
这可以保证执行整个事务,或者不执行任何事务。执行此操作时,您可能还需要锁定表,以确保其他进程的外观一致。在
确切地说,您做什么以及如何做通常取决于数据库,因为事务处理和行与表锁定之间的关系因数据库和引擎而异。在
相关问题 更多 >
编程相关推荐