Python 2.7 选择更新语句在芹菜任务中不工作

Python 2.7 选择更新语句在芹菜任务中不工作,python-2.7,celery,django-1.11,Python 2.7,Celery,Django 1.11,我正在开发一些需要在数据库中保存大量数据的代码。响应大约需要一分钟或更长时间。所以我决定将代码移到芹菜任务中。我有一种观点叫芹菜任务。 这里的问题是,若芹菜任务仍在为数据库中的同一条记录运行,那个么您就不能从该视图接收状态200 在那里,我对行级锁使用select\u for\u update语句,如: site = self.get_object() try: with transaction.atomic(): Site.object

我正在开发一些需要在数据库中保存大量数据的代码。响应大约需要一分钟或更长时间。所以我决定将代码移到芹菜任务中。我有一种观点叫芹菜任务。 这里的问题是,若芹菜任务仍在为数据库中的同一条记录运行,那个么您就不能从该视图接收状态200

在那里,我对行级锁使用select\u for\u update语句,如:

    site = self.get_object()

    try:
        with transaction.atomic():
            Site.objects.select_for_update(nowait=True).filter(pk=site.pk)
    except DatabaseError:
        raise ObjectLockedException
鉴于:

    with transaction.atomic():
        models.Site.objects.select_for_update(nowait=True).get(pk=site_id)
        ....
在任务中。如您所见,代码是相同的

我的预期结果是,如果芹菜任务已启动并获取了具有Site_id的特定站点的锁,但尚未完成,我应该在指定视图中捕获DatabaseError。 情况并非如此,请在视图中选择\u以进行\u更新,即使同一站点的任务仍在运行,也不例外

另一件有趣的事情是,在指定的视图中,在第一段代码下面的online serializer.save()中,我的代码等待任务完成处理


我做错了吗?

带有的
块是一个上下文管理器。当控制流离开该块时,上下文关闭,即事务结束。您正在锁定记录,但未对其进行操作


尝试将更新移动到
with
块中。

with
块是一个上下文管理器。当控制流离开该块时,上下文关闭,即事务结束。您正在锁定记录,但未对其进行操作


尝试将更新移动到
with
块中。

如果我在
with
块中移动serializer.save(),任务将在select_for_update时引发异常,就像我在特定行上遇到死锁一样。这里的问题可能是我重写了model.save()方法,并在其中调用了我的任务。因此,我假设在serializer.save()完成之前触发任务中更新的select_。即使我将任务在视图中的调用移动到
serializer.save()
之后,视图在
serializer.save()
上被阻止,而上一个任务尚未完成。对我来说真的很奇怪。我想知道您是否有在视图和任务中运行的相互排斥的数据库查询。如果是这样的话,很有可能您最终会得到一个数据库锁。它们是独占的。在视图(序列化程序)中,我只更新站点对象的一个字段。任务应使用相关对象(具有站点id外键的对象)填充数据库。我只想知道,如果任务仍在用相关对象填充数据库,则不能调用此视图。出于某种原因,serializer.save()正在等待任务完成,然后再次触发任务。我现在真的很困惑,实际上我刚刚发现了一些可能有效的方法,但仍然不确定发生了什么。似乎存在这个问题,因为我对站点对象使用了
pre_save
方法。如果我将
select\u for\u update
放入
pre\u save
方法中,这似乎是可行的。它类似于
pre\u save
方法从视图中移除锁。如果我将
中的serializer.save()与
块一起移动,该任务将在select\u for\u更新时引发异常,就像我在特定行上遇到死锁一样。这里的问题可能是我重写了model.save()方法,并在其中调用了我的任务。因此,我假设在serializer.save()完成之前触发任务中更新的select_。即使我将任务在视图中的调用移动到
serializer.save()
之后,视图在
serializer.save()
上被阻止,而上一个任务尚未完成。对我来说真的很奇怪。我想知道您是否有在视图和任务中运行的相互排斥的数据库查询。如果是这样的话,很有可能您最终会得到一个数据库锁。它们是独占的。在视图(序列化程序)中,我只更新站点对象的一个字段。任务应使用相关对象(具有站点id外键的对象)填充数据库。我只想知道,如果任务仍在用相关对象填充数据库,则不能调用此视图。出于某种原因,serializer.save()正在等待任务完成,然后再次触发任务。我现在真的很困惑,实际上我刚刚发现了一些可能有效的方法,但仍然不确定发生了什么。似乎存在这个问题,因为我对站点对象使用了
pre_save
方法。如果我将
select\u for\u update
放入
pre\u save
方法中,这似乎是可行的。它类似于
pre_save
方法从视图中移除锁。