django过滤和更新

时间:2016-09-13 22:36:40

标签: django django-models django-queryset

更新: 我为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)resource1resource2是我模型中的不同资源。从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来锁定条目。但是,我不想锁定和更新所有可用资源。

请建议是否有任何方法可以一次检索和更新?

1 个答案:

答案 0 :(得分:1)

select_for_update将仅锁定行,因此在查询中first()只会锁定一行。

因此 - 使用select_for_update