【发布时间】:2018-07-25 10:39:22
【问题描述】:
我有一个类似这个例子的模型
class Foo(models.Model):
a = models.ForeignKey(...)
number = models.IntegerField()
@transaction.atomic
def save(self, commit=True):
if self.pk is None:
current_max = (
Foo.objects
.filter(a=self.a)
.order_by('-number')
.first()
)
current_max = 0 if current_max is None else current_max.number
self.number = current_max + 1
return super().save(commit)
这个想法是对于每个a,都会有一系列Foos,从1开始编号。
问题是,即使我们有@transaction.atomic,也存在竞争条件,因为 Django 期望的事务隔离级别将允许事务同时运行,即
A -> Get max -> 42
B -> Get max -> 42
A -> Set max + 1
A -> save
B -> Set max + 1
B -> save
Both will be 43
那我该如何解决呢?有没有办法自动设置计数器,这样我就不会在检索当前最大值和插入新值之间出现竞争条件?
这个问题是similar to this one,但不同的是,这个问题没有为我的具体示例提供答案
【问题讨论】:
标签: django transactions race-condition