Django中的隔离与并发

Isolation and concurrence in Django

我正在将 DjangoREST 与 PostgreSQL 结合使用。我有这两个模型: author/models.py:

class Author(models.Model):
     name = models.CharField(max_length=256)
     allsize =  models.FloatField(default=0)

并在 files/models.py:

class File(models.Model):
     author =  models.ForeignKey(Author, on_delete=models.CASCADE)
     name = models.CharField(max_length=256)
     size = models.FloatField(default=0)

如果我上传多个大小相同的文件(从前端),为了更新作者的 allsize 字段(这是所有上传文件的总和),DjangoREST 没有正确更新值也许根据并发性(它们具有相同的大小),尽管我正在做一个原始的 sql 事务:

    with connection.cursor() as cursor:
        cursor.execute("BEGIN; set transaction isolation level read committed;"
                        "update author_author set allsize = allsize + %s where author_id = %s;",
                               [validated_data.get('size', 0), validated_data.get('author', 0)])
        cursor.execute("COMMIT;")

allsize字段实际上是一个重复的数据。该信息已存在于您的数据库中(与此用户相关的所有 File.size 的总和)。

如果您想获取给定 Author 的此信息,您可以使用:

class Author(models.Model):
     name = models.CharField(max_length=256)

     def all_size(self):
        return self.aggregate(all_size=Sum('files__size')).all_size

这样,您就没有数据重复,并且可以轻松获得 聚合

更多资源在Django docs

我的 SQL 交易有效,我的代码有错误。