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

Django中使用get_or_create创建模型时如何锁定读取避免并发异常?

解决Django get_or_create并发下对象初始化不完整的问题

核心问题

并发场景下,get_or_create创建对象后,第三方接口调用(慢操作)还未完成、维度数据未保存时,第二个请求会读取到状态不完整的对象,导致后续依赖维度的代码逻辑异常。

解决方案:事务+行级锁

利用Django的事务和数据库行级锁,将对象创建+维度数据初始化的整个流程变成原子操作,确保其他请求只能等到整个流程完成后,才能读取到完整的对象。

代码实现

from django.db import transaction

with transaction.atomic():
    # 使用select_for_update对目标行加排他锁
    model, created = SomeModel.objects.select_for_update().get_or_create(
        user=user,
        name=name,
        defaults={...}  # 初始字段值
    )
    if created:
        # 调用第三方接口获取维度数据
        created_dimensions = get_some_dimensions()
        # 关联维度数据并保存
        model.dimension_values.set(created_dimensions)
        model.save()

# 依赖模型维度数据的代码

原理说明

  • select_for_update()会对查询到的数据库行加排他锁,其他事务尝试读取或修改该行时,会被阻塞直到当前事务提交。
  • transaction.atomic()确保整个代码块内的操作要么全部完成提交,要么全部回滚,避免出现中间状态的对象被读取。
  • 只有当维度数据处理完成、事务提交后,其他请求才能获取到完整的对象状态。

备选方案:增加状态字段(需修改模型)

如果无法依赖数据库行级锁,可以给模型增加状态字段标记对象是否初始化完成:

  1. 先给SomeModel添加状态字段:
class SomeModel(models.Model):
    # 原有字段...
    STATUS_CHOICES = (
        ('pending', '初始化中'),
        ('complete', '已完成'),
    )
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
  1. 业务代码实现:
from django.db import transaction
import time

with transaction.atomic():
    model, created = SomeModel.objects.get_or_create(
        user=user,
        name=name,
        defaults={'status': 'pending', ...}
    )
    if created:
        created_dimensions = get_some_dimensions()
        model.dimension_values.set(created_dimensions)
        model.status = 'complete'
        model.save()
    else:
        # 如果对象存在但未初始化完成,加锁等待状态更新
        model = SomeModel.objects.select_for_update().get(user=user, name=name)
        while model.status != 'complete':
            time.sleep(0.1)  # 短暂休眠后刷新状态
            model.refresh_from_db()

# 此处model的status必定为complete,可安全执行依赖维度的代码

注意事项

  • select_for_update()依赖数据库对行级锁的支持,需使用InnoDB(MySQL)、PostgreSQL等支持行级锁的存储引擎,MyISAM不适用。
  • 事务执行时间会因第三方接口的延迟而变长,需评估并发场景下的锁等待对系统性能的影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 18:15:01