我有一个Django 1.11 + MySQL + Celery 4.1项目,其中一个视图创建一个新的用户记录,然后启动Celery任务以执行与之相关的其他长时间运行的操作。
这种情况下的典型问题是确保在Celery任务执行之前将用户创建提交到数据库。否则,就会出现竞争条件,如果在事务提交之前执行该记录,任务可能会尝试访问不退出的记录。
我学会解决这个问题的方法是始终将记录创建包装在手动事务或原子块中,然后在此之后触发Celery任务。 e.g。
def create_user():
with transaction.atomic():
user = User.objects.create(username='blah')
mytask.apply_async(args=[user.id])
@task
def mytask(user_id):
user = User.objects.get(id=user_id)
do_stuff(user)
但是,我偶尔会在Celery工作日志中看到错误DoesNotExist: User matching query does not exist
,这意味着我的任务有时会在提交用户记录之前执行。
这不是正确的策略,还是我没有正确实施?
答案 0 :(得分:0)
我认为post_save
信号更适合您尝试做的事情:https://docs.djangoproject.com/en/1.11/ref/signals/#post-save。此信号将created
参数作为布尔值发送,使其仅在对象创建时易于操作。