【发布时间】:2016-05-15 05:44:14
【问题描述】:
我有一个 Django 应用程序将对象保存到数据库和一个 celery 任务,它定期对其中一些对象进行一些处理。问题是用户可以删除一个对象在它已被 celery 任务选择进行处理,但 在之前 celery 任务实际上已完成处理并保存它。因此,当 celery 任务确实调用 .save() 时,即使用户删除了该对象,该对象仍会重新出现在数据库中。当然,这对用户来说真的很吓人。
所以这里有一些显示问题的代码:
def my_delete_view(request, pk):
thing = Thing.objects.get(pk=pk)
thing.delete()
return HttpResponseRedirect('yay')
@app.task
def my_periodic_task():
things = get_things_for_processing()
# if the delete happens anywhere between here and the .save(), we're hosed
for thing in things:
process_thing(thing) # could take a LONG time
thing.save()
我曾想过尝试通过添加一个原子块和一个事务来修复它,以在保存之前测试该对象是否确实存在:
@app.task
def my_periodic_task():
things = Thing.objects.filter(...some criteria...)
for thing in things:
process_thing(thing) # could take a LONG time
try:
with transaction.atomic():
# just see if it still exists:
unused = Thing.objects.select_for_update().get(pk=thing.pk)
# no exception means it exists. go ahead and save the
# processed version that has all of our updates.
thing.save()
except Thing.DoesNotExist:
logger.warning("Processed thing vanished")
这是做这种事情的正确模式吗?我的意思是,我会在生产中运行它的几天内找出它是否可以工作,但如果有其他被广泛接受的模式来完成这类事情,我会很高兴。
我真正想要的是能够更新一个对象如果它仍然存在于数据库中。我对用户编辑和来自process_thing 的编辑之间的竞争感到满意,我总是可以在process_thing 之前输入refresh_from_db,以最大限度地减少用户编辑丢失的时间。但我绝对不能让对象在用户删除它们后重新出现。
【问题讨论】:
标签: python django locking celery database-locking