如何在 django 中创建模型时锁定读取访问权限?

问题描述 投票:0回答:1

我们注意到 django 应用程序中使用 get_or_create 时存在很多问题。

model, created = SomeModel.objects.get_or_create(user=user, name=name, defaults={...});
if created:
    get_some_dimensions # SLOW as we call to third party
    model.dimension_values.set(created_dimensions)

# Code here that depends on dimensions being there for the model

问题是上面的代码同时运行了两次。

  1. 第一次创建模型时,它开始“get_some_dimensions”,但没有完成(因此未保存)
  2. 然后第二次运行,它看到模型已经在那里了
  3. 但是,在第一次运行保存之前,第二次运行会转到“此处的代码取决于尺寸”。

在第 3 步,数据库转换为错误状态。

如何防止第二次实际运行,锁定数据库,直到构建完整对象?

django postgresql concurrency
1个回答
0
投票

将其包装在交易中?

with transaction.atomic():

    model, created = SomeModel.objects.get_or_create(user=user, name=name, defaults={...});
    if created:
        get_some_dimensions # SLOW as we call to third party
        model.dimension_values.set(created_dimensions)        
        # model.save() if .set doesn't do that

# the object doesn't exist until here where the transaction completes (exit with block)

但我不是数据库专家,所以我不确定如果在第三方速度缓慢时发生另一个

get_or_create
会发生什么。数据库是否会停止第二个操作直到事务终止?如果第三方请求可能需要几十秒,用户是否会认为这是一个错误?

另一种方法是测试是否

SomeModel.objects.filter(...).exists()
,如果不是,则在执行
get_or_create
之前向慢速第三方请求信息(向该调用提供第三方信息,以便在完整状态下创建对象)。这里唯一的缺点是可能会向第三方重复请求不需要的信息。 (每次通话要花很多钱吗?)

© www.soinside.com 2019 - 2024. All rights reserved.