python - 如何通过 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)
是否可以在不达到数据库级别约束的情况下异步运行我的缓冲区?
解决方案
推荐阅读
- python - 有条件地用另一个类方法装饰类方法
- django - 通过 parsepy 查询 mogodb 时使用 __startswith(或类似类型)返回空查询集
- sparql - 带有语言过滤器的 SPARQL 查询模板
- .net - MessageBox 仅在表单关闭后显示
- cordova - Apache Cordova `resolveLocalFileSystemURL` 函数总是返回错误 5 (ENCODING_ERR)
- android-studio - “您需要为您的 APK 或 Android App Bundle 使用不同的版本代码”无论设置什么版本代码
- c# - NLog 布局渲染器似乎在配置中不起作用
- r - 将嵌套 tibble 的所有列取消嵌套到 tibble 列表
- javascript - Vuejs中列表对象中文本的样式部分
- python - 如何防止程序等待接收来自客户端的消息?