You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中create()与get()间数据库竞态问题求助

问题分析与解决方案

核心原因是Django默认事务提交时机与异步任务执行的竞态:
Django默认会在请求/函数执行完毕后才自动提交事务,Model.objects.create()返回对象时,数据仅在当前事务内可见,并未提交到PostgreSQL。而django-rq的worker使用独立的数据库连接,PostgreSQL默认READ COMMITTED隔离级别下,无法读取未提交的事务数据,因此异步任务执行时会出现找不到对象的情况。测试环境负载低,事务提交速度快,所以难以复现。


具体解决方案

1. 手动控制事务提交时机

在创建对象后立即提交事务,再触发异步任务:

from django.db import transaction

def create_object_and_run_job():
    # 用atomic块包裹创建逻辑,块结束自动提交事务
    with transaction.atomic():
        x = Model.objects.create()
    # 事务已提交,确保数据落地后再触发任务
    job.delay(x_id=x.id)

如果是在视图函数中,也可以显式调用transaction.commit()(注意避免影响其他逻辑)。

2. 使用django-rq的事务提交后触发机制

django-rq原生支持transaction_on_commit参数,确保任务在当前事务提交后再入队:

from django_rq import get_queue

def create_object_and_run_job():
    x = Model.objects.create()
    # 传入transaction_on_commit=True,等待事务提交再执行任务
    get_queue().enqueue(job, x_id=x.id, transaction_on_commit=True)

也可以在任务装饰器中全局配置:

from django_rq import job

@job(transaction_on_commit=True)
def your_async_job(x_id):
    obj = Model.objects.get(id=x_id)
    # 任务业务逻辑

3. 给异步任务添加重试兜底

即使前面的措施没完全覆盖,给任务加重试机制可以应对偶发的竞态情况:

from django_rq import job
from django.core.exceptions import ObjectDoesNotExist

# 最多重试3次,每次间隔1秒
@job(retry=3, retry_delay=1)
def your_async_job(x_id):
    try:
        obj = Model.objects.get(id=x_id)
    except ObjectDoesNotExist:
        # 抛出异常触发重试
        raise
    # 后续业务逻辑

4. 排查嵌套事务问题

如果代码中存在嵌套事务(比如外层有atomic块),内层事务的create操作不会立即提交,需要确保外层事务在触发任务前已提交。可以通过transaction.get_connection().in_atomic_block()检查当前是否处于事务中。


排查建议

  • 开启Django的事务日志,添加LOGGING配置跟踪事务提交事件,对比任务执行时间点,确认竞态窗口:
    LOGGING = {
        # ...其他配置
        'loggers': {
            'django.db.backends': {
                'level': 'DEBUG',
                'handlers': ['console'],
                'filters': ['require_debug_true'],
            },
        },
    }
    
  • 检查生产环境数据库的连接池配置,确认worker的数据库连接是否存在事务复用问题。

内容的提问来源于stack exchange,提问作者Henty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 07:02:49