带有Celery的Django-找不到现有对象 [英] Django with Celery - existing object not found
问题描述
我在从另一个芹菜任务执行芹菜任务时遇到问题。
I am having problem with executing celery task from another celery task.
这里是有问题的代码段(数据对象已存在于数据库中,其属性只是在内部更新finalize_data函数):
Here is the problematic snippet (data object already exists in database, its attributes are just updated inside finalize_data function):
def finalize_data(data):
data = update_statistics(data)
data.save()
from apps.datas.tasks import optimize_data
optimize_data.delay(data.pk)
@shared_task
def optimize_data(data_pk):
data = Data.objects.get(pk=data_pk)
#Do something with data
optimize_data函数中的Get调用失败,并显示不存在数据匹配查询。
Get call in optimize_data function fails with "Data matching query does not exist."
如果我在finalize_data函数中调用pk函数进行检索,则效果很好。如果我将celery任务调用延迟了一段时间,它也可以正常工作。
If I call the retrieve by pk function in finalize_data function it works fine. It also works fine if I delay the celery task call for some time.
此行:
optimize_data.apply_async((data.pk,), countdown=10)
而不是
optimize_data.delay(data.pk)
工作正常。但是我不想在代码中使用hack。 .save()调用是否可能异步阻止对该行/对象的访问?
works fine. But I don't want to use hacks in my code. Is it possible that .save() call is asynchronously blocking access to that row/object?
推荐答案
我猜您的调用方在芹菜开始处理任务之前尚未提交的事务中。因此,芹菜找不到记录。这就是为什么添加倒数计时使其有效的原因。
I'm guessing your caller is inside a transaction that hasn't committed before celery starts to process the task. Hence celery can't find the record. That is why adding a countdown makes it work.
在您的示例中,倒数1秒的效果可能与10秒的倒数效果一样。我在整个代码中都使用了1秒的倒计时来解决此问题。
A 1 second countdown will probably work as well as the 10 second one in your example. I've used 1 second countdowns throughout code to deal with this issue.
另一种解决方案是停止使用事务。
Another solution is to stop using transactions.
这篇关于带有Celery的Django-找不到现有对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!