在transaction.atomic()中的django select_for_update(nowait=False)无法按预期工作

qlvxas9a  于 2022-11-26  发布在  Go
关注(0)|答案(1)|浏览(106)

我有一个Django应用需要一个唯一的ID。许多线程同时运行,需要一个。我希望ID是连续的。当我需要一个唯一的ID时,我这样做:

with transaction.atomic():
    max_batch_id = JobStatus.objects.select_for_update(nowait=False).aggregate(Max('batch_id'))
    json_dict['batch_id'] = max_batch_id['batch_id__max'] + 1
    status_row = JobStatus(**json_dict)
    status_row.save()

但是多个作业获得了相同的ID。为什么代码不能按我预期的方式工作?有什么更好的方法来完成我所需要的?我不能使用行ID,因为有许多行具有相同的batch_id。

ar7v8xwq

ar7v8xwq1#

正如Django docs在Docs中所说,你可以使用F()来避免竞态条件:
这个过程可以变得健壮,避免竞争条件,并且通过表达相对于原始字段值的更新,而不是显式地赋值新值,来稍微加快速度。Django提供了F表达式来执行这种相对更新。
所以你可能想要这样的东西:

...
max_batch_id = JobStatus.objects.select_for_update(nowait=False).aggregate(Max(F('batch_id')))
...

相关问题