原子事务是否应该在 Django 中产生更多 connection.queries?

Are atomic transactions supposed to produce more connection.queries in Django?

我的模型中有以下内容:

from django.db import models

class X(models.Model):
    ...

class Y(models.Model):
    ...
    x = models.ForeignKey(X, on_delete=models.CASCADE)


class Z(models.Model):
    ...
    y = models.ForeignKey(Y, on_delete=models.CASCADE)

在我的一个观点中,我正在更新我的所有模型:

from .models import X, Y, Z
from django.db import connection, transaction


def do_something(bro, z_pk):
    z = Z.objects.select_related('y__x').get(pk=z_pk)
    y = z.y
    x = y.x

    ...

    with transaction.atomic():
        z.save()
        y.save()
        x.save()

    print(len(connection.queries))

transaction.atomic(),查询的长度为5,没有transaction.atomic(),返回的长度为4,即如下代码:

from .models import X, Y, Z
from django.db import connection


def do_something(bro, z_pk):
    z = Z.objects.select_related('y__x').get(pk=z_pk)
    y = z.y
    x = y.x

    ...

    z.save()
    y.save()
    x.save()

    print(len(connection.queries))

Returns 长度为 4。这是正常现象还是我遗漏了什么?此外,使用 transaction.atomic(),我访问数据库的次数是否减少了?很难理解,基于connection.queries.

注意:原子函数中的额外查询如下:

{'sql': 'BEGIN', 'time': '0.000'}

BEGIN 语句只是 PostgreSQL 启动事务的方式。这就是为什么您会在交易示例中看到它。 (也应该有一个COMMIT语句,但也许Django不计算它。)

没有显式事务 Django 和数据库在 autocommit mode 中运行,因此不需要额外的语句。

请注意,查询次数与您"hit the database"的次数不同,因为可以同时发送多个查询。 (我不确定 Django 是否有办法报告对数据库进行了多少次往返。)无论如何,我认为可以肯定地说,无需担心执行BEGIN 声明。 (尽管通常使用事务会对应用程序的整体性能产生影响。)