Django并发获取和增量
Django concurrent get-and-increment
假设我有一个模型 A,它有一个 account_number 字段,当创建 A 的新实例时 [=23=我模型中的 ]counter 字段 B 将其值递增 1。该值与我的 account_number 字段将接收到的值相同。
我想保护操作免受并发修改,以便我的 account_number 始终是正确的。
我想做如下事情:
instance.account_number = F('modelB_table.counter') + 1
同时更新 counter B[=44 中的值=]
如何在 Django 1.9 中实现此功能?
交易在这种情况下会有帮助吗?
是的,您可以在 Django 中使用事务来实现这一点。你会做类似的事情:
with transaction.atomic():
ModelB.objects.update(counter=F('counter') + 1)
new_counter = ModelB.objects.get().counter
a_instance.account_number = new_counter
a_instance.save()
这需要在 READ_COMMITTED
或更高的事务隔离级别上完成。 (在 PostgreSQL 中,默认隔离级别是 READ_COMMITTED
,我不确定其他数据库。)
之所以有效,是因为该隔离级别使得脏读成为不可能,因此在其他事务提交之前,并发事务无法更新计数器。
假设我有一个模型 A,它有一个 account_number 字段,当创建 A 的新实例时 [=23=我模型中的 ]counter 字段 B 将其值递增 1。该值与我的 account_number 字段将接收到的值相同。
我想保护操作免受并发修改,以便我的 account_number 始终是正确的。
我想做如下事情:
instance.account_number = F('modelB_table.counter') + 1
同时更新 counter B[=44 中的值=]
如何在 Django 1.9 中实现此功能?
交易在这种情况下会有帮助吗?
是的,您可以在 Django 中使用事务来实现这一点。你会做类似的事情:
with transaction.atomic():
ModelB.objects.update(counter=F('counter') + 1)
new_counter = ModelB.objects.get().counter
a_instance.account_number = new_counter
a_instance.save()
这需要在 READ_COMMITTED
或更高的事务隔离级别上完成。 (在 PostgreSQL 中,默认隔离级别是 READ_COMMITTED
,我不确定其他数据库。)
之所以有效,是因为该隔离级别使得脏读成为不可能,因此在其他事务提交之前,并发事务无法更新计数器。