首页 > 解决方案 > 如何通过 Django 中的 celery 异步任务处理数据库条目的创建

问题描述

我的系统从另一个来源接收有效负载。此有效载荷包含项目信息,包括品牌等。

我将此有效负载保存在缓冲区中。缓冲区与 Celery 任务异步处理。根据负载,我们创建条目或在必要时更新它们。这是通过使用原子事务来完成的,我们在其中创建项目、品牌和类别。

我遇到的问题是,两个缓冲区可能都有一个尚未在数据库中创建的 Brand。在原子块中使用 update_or_create 我检查它是否已经存在。由于两个缓冲区几乎在同一时间异步运行,因此两者都认为该品牌尚不存在。这意味着他们俩都尝试创建品牌,导致我出现以下数据库错误:

postgres_1 | 错误:重复键值违反唯一约束“catalogue_brand_name_key” postgres_1 | 详细信息:键(名称)=(Bic)已经存在。postgres_1 | 声明:插入“catalogue_brand”(“id”、“created_date”、“modified_date”、“name”)值('c8e9f328-cee7-4b9b-ba45-268180c723d8'::uuid,'2018-12-28T08:08: 51.519672+00:00'::timestamptz, '2018-12-28T08:08:51.519691+00:00'::timestamptz, 'Bic')

由于这是一个 db 级异常,我无法在我的代码中捕获它,并且缓冲区将被标记为已完成(因为代码中没有给出异常)。

这里的简单解决方案是不异步运行缓冲区,而一次只运行一个。

这是我的部分代码:

@atomic
def create(self, data):

...


brand_obj = Brand.objects.update_or_create(
        name=brand['name'],
        defaults={
            'name': brand['name']
        }
     )[0]

...

通过以下方式调用:

process_incoming.delay(buffer.pk)

是否可以在不达到数据库级别约束的情况下异步运行我的缓冲区?

标签: pythondjangopostgresqltransactionscelery

解决方案


推荐阅读