По умолчанию "transaction.atomic" уже применяется к данным, которые добавляются и изменяются в Django Admin?

Я проверил репозиторий Django на GitHub. Затем, transaction.atomic(using=using, savepoint=False) и transaction. mark_for_rollback_on_error(using=using) вызываются в save_base(), которая вызывается в save() в классе Model(metaclass=ModelBase): как показано ниже:

# "django/django/db/models/base.py"

class Model(metaclass=ModelBase):
    # ...
    def save(
        self, force_insert=False, force_update=False, using=None, update_fields=None
    ):
        # ...
        self.save_base(
            using=using,
            force_insert=force_insert,
            force_update=force_update,
            update_fields=update_fields,
        )
    # ...    
    def save_base(
        self,
        raw=False,
        force_insert=False,
        force_update=False,
        using=None,
        update_fields=None,
    ):
        # ...  
        # A transaction isn't needed if one query is issued.
        if meta.parents:
            context_manager = transaction.atomic(using=using, savepoint=False) # Here
        else:
            context_manager = transaction.mark_for_rollback_on_error(using=using) # Here
        with context_manager:
            # ...

Итак, по умолчанию, "transaction.atomic" уже применяется к данным, которые добавляются и изменяются в Django Admin, верно?

Другими словами, при добавлении и изменении данных в Django Admin, данные по умолчанию atomic, верно?

Итак, в "class Person(models.Model):", если мы переопределим "save()", который вызывает "super().save(*args, **kwargs)" в нем, как показано ниже:

# "models.py"

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs) # Here

Нам не нужно ставить "@transaction.atomic" на "save()" как показано ниже, верно?

# "models.py"

from django.db import models
from django.db import transaction

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

    @transaction.atomic # Don't need
    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

Или нам не нужно использовать "with transaction.atomic():" в "save()" как показано ниже, верно?

# "models.py"

from django.db import models
from django.db import transaction

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

    def save(self, *args, **kwargs):
        with transaction.atomic(): # Don't need
            super().save(*args, **kwargs)

За исключением Djang Admin Actions, по умолчанию transaction всегда используется для Django Admin независимо от того, переопределены ли save(), overridden save() имеет super().save() и overridden save() имеет @transaction.non_atomic_requests или нет. Итак, нам не нужны @transaction.atomic или with transaction.atomic(): для overridden save() и не нужно устанавливать 'ATOMIC_REQUESTS': True в настройки базы данных в settings.py. *Мой пост объясняет, как отключить транзакцию для Django Admin и Мой пост объясняет о Django Admin Actions with non- транзакциями по умолчанию.

Я экспериментировал, если по умолчанию transaction всегда используется для Django Admin. Я использовал PostgreSQL. *Вы также можете посмотреть мой ответ , в котором экспериментируется, используется ли Atomic Transaction для Django View по умолчанию или нет:

Для неопределенных save() как показано ниже:

# "store/models.py"

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=30)

    # def save(self, *args, **kwargs): # Here
    #     super().save(*args, **kwargs) # Here

Или для переопределенных save() с super().save() и @transaction.non_atomic_requests, как показано ниже:

# "store/models.py"

from django.db import models
from django.db import transaction

class Person(models.Model):
    name = models.CharField(max_length=30)
    
    @transaction.non_atomic_requests # Here
    def save(self, *args, **kwargs): # Here
        super().save(*args, **kwargs) # Here

Я добавляю John:

enter image description here

<<<Затем,

между запросами "BEGIN" и "COMMIT" выполняются INSERT два запроса, как показано ниже. *Эти журналы ниже являются журналами запросов PostgreSQL. Вы можете проверить в PostgreSQL, как регистрировать SQL-запросы с транзакционными запросами, такими как "BEGIN" и "COMMIT":

enter image description here

Далее обновляем John до Tom:

enter image description here

Затем, между запросами SELECT, UPDATE и INSERT выполняются запросы "BEGIN" и "COMMIT" как показано ниже:

enter image description here

Далее, удалите Tom:

enter image description here

Затем, между запросами SELECT, INSERT и DELETE выполняются запросы "BEGIN" и "COMMIT" как показано ниже:

enter image description here

Далее, для переопределенных save() без super().save(), но с @transaction.non_atomic_requests:

# "store/models.py"

from django.db import models
from django.db import transaction

class Person(models.Model):
    name = models.CharField(max_length=30)
    
    @transaction.non_atomic_requests # Here
    def save(self, *args, **kwargs): # Here
        pass
        # super().save(*args, **kwargs)

Я добавляю John. *На самом деле, John не добавляется, потому что переопределенный save() не имеет super().save():

enter image description here

Затем, один INSERT запрос выполняется между запросами "BEGIN" и "COMMIT" как показано ниже:

enter image description here

Так как эксперименты выше, мы видим, что по умолчанию transaction всегда используется для Django Admin независимо от того, переопределены save() или нет, overridden save() имеет super().save() и overridden save() имеет @transaction.non_atomic_requests. Поэтому, опять же, нам не нужно использовать @transaction.atomic или with transaction.atomic(): для overridden save().

Кроме того, для переопределенных save() с super().save() и @transaction.atomic как показано ниже:

# "store/models.py"

from django.db import models
from django.db import transaction

class Person(models.Model):
    name = models.CharField(max_length=30)
    
    @transaction.atomic # Here
    def save(self, *args, **kwargs): # Here
        super().save(*args, **kwargs) # Here

Или, для переопределенных save() с super().save() и with transaction.atomic():, как показано ниже:

# "store/models.py"

from django.db import models
from django.db import transaction

class Person(models.Model):
    name = models.CharField(max_length=30)
    
    def save(self, *args, **kwargs): # Here
        
        with transaction.atomic(): # Here
            super().save(*args, **kwargs) # Here

Я добавляю John:

enter image description here

Затем, один SAVEPOINT и RELEASE SAVEPOINT и два INSERT запроса выполняются между запросами "BEGIN" и "COMMIT" , как показано ниже:

enter image description here

Далее, для переопределите save() с super().save(), как показано ниже:

# "store/models.py"

from django.db import models
from django.db import transaction

class Person(models.Model):
    name = models.CharField(max_length=30)
    
    def save(self, *args, **kwargs): # Here
        super().save(*args, **kwargs) # Here

Я установил 'ATOMIC_REQUESTS': True в PostgreSQL settings в settings.py:

# "core/settings.py"

DATABASES = {
    'default':{
        'ENGINE':'django.db.backends.postgresql',
        'NAME':'postgres',
        'USER':'postgres',
        'PASSWORD':'admin',
        'HOST':'localhost',
        'PORT':'5432',
        'ATOMIC_REQUESTS': True, # Here
    }
}

Затем, я добавляю John, как показано ниже:

enter image description here

Затем между запросами "BEGIN" и "COMMIT" выполняются SELECT два INSERT и SAVEPOINT и один RELEASE SAVEPOINT и , как показано ниже:

enter image description here

Далее, для переопределенных save(), я поместил оба @transaction.atomic и with transaction.atomic():, как показано ниже:

# "store/models.py"

from django.db import models
from django.db import transaction

class Person(models.Model):
    name = models.CharField(max_length=30)
    
    @transaction.atomic # Here
    def save(self, *args, **kwargs): # Here
        
        with transaction.atomic(): # Here
            super().save(*args, **kwargs) # Here

И, я также установил 'ATOMIC_REQUESTS': True в PostgreSQL settings в settings.py как показано ниже:

# "core/settings.py"

DATABASES = {
    'default':{
        'ENGINE':'django.db.backends.postgresql',
        'NAME':'postgres',
        'USER':'postgres',
        'PASSWORD':'admin',
        'HOST':'localhost',
        'PORT':'5432',
        'ATOMIC_REQUESTS': True, # Here
    }
}

Затем, я добавляю John, как показано ниже:

enter image description here

Затем между запросами "BEGIN" и "COMMIT" выполняются SELECT два INSERT и SAVEPOINT и три RELEASE SAVEPOINT и , как показано ниже:

enter image description here

Вернуться на верх