更新:
我为select_for_update
做了一些测试。我正在使用django 1.8.12。我在不同的shell中运行以下函数,连接到我的本地mariadb(引擎是InnoDB)。似乎select_for_update
也会锁定其他行?不确定我是否以正确的方式进行了测试:
def with_sleep(resource):
try:
with transaction.atomic():
resource = resourceA.objects.select_for_update().filter(A=resource).first()
print('before sleep')
time.sleep(10)
print('after sleep')
resource.available = False
resource.save()
return True
except:
handle_exception()
def withouth_sleep(resource):
try:
with transaction.atomic():
print('try')
resource = resourceA.objects.select_for_update().filter(A=resource).first()
print('get resource')
resource.available = False
print('save')
resource.save()
return True
except:
handle_exception()
我先调用with_sleep(resource1)
函数,然后调用without_sleep(resource2)
。 resource1
和resource2
是我模型中的不同资源。从shell开始,我看到try
之后第二个函数被阻塞,直到第一个函数从睡眠状态唤醒。这是否意味着资源2的行也被锁定了?
这个问题可能听起来很愚蠢。感谢您提供任何建议或任何测试更改。
原始问题: 我有一个资源模型,它检查资源是否可用,并且它在2个服务器中运行多个芹菜工作者,以便每次检索下一个可用资源。如果可用,将其状态更改为不可用并分配给任务。
例如:
Class resourceA(model.Model):
A = models.CharField(max_length=10)
available = models.BooleanField(default=True)
每次,我只想选择下一个可用资源并分配给任务。 如果我做
resource = resourceA.objects.filter(available=True).first()
if resource:
resource.available=False
resource.save()
然后其他工作人员可能会获取相同的资源并尝试更新它。
Django有select_for_update
来锁定条目。但是,我不想锁定和更新所有可用资源。
请建议是否有任何方法可以一次检索和更新?
答案 0 :(得分:1)
select_for_update
将仅锁定行,因此在查询中first()
只会锁定一行。
因此 - 使用select_for_update
。