django数据库事务操作celery任务注意事项

发布时间 2023-10-04 12:16:46作者: 蕝戀
from django.db import transaction
from django.http import HttpResponseRedirect

@transaction.atomic
def create_article(request):
    article = Article.objects.create()
    expand_abbreviations.delay(article.pk)
    return HttpResponseRedirect('/articles/')

这是一个 Django 视图,在数据库中创建文章对象,然后将主键传递给任务。它使用 transaction.atomic 装饰器,该装饰器将在视图返回时提交事务,或者在视图引发异常时回滚。

如果任务(expand_abbreviations)在事务提交之前开始执行,则存在竞争条件;数据库对象还不存在!

解决方案是在所有事务成功提交后使用 on_commit 回调启动 Celery 任务。

from django.db import transaction
from django.http import HttpResponseRedirect

@transaction.atomic
def create_article(request):
    article = Article.objects.create()
    transaction.on_commit(lambda: expand_abbreviations.delay(article.pk))
    return HttpResponseRedirect('/articles/')