默认情况下,Django管理员是否已经使用了事务?

7lrncoxx  于 2022-12-14  发布在  Go
关注(0)|答案(1)|浏览(138)

我检查了GitHub上的Django仓库。然后,**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已经被用于Django Admin,对吗?
因此,在**class Person(models.Model):中,如果我们重写save(),它在其中调用super().save(*args, **kwargs)**,如下所示:

# "models.py"

from django.db import models

class Person(models.Model):
    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):
    name = models.CharField(max_length=30)

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

或者,我们不需要在**save()中使用with transaction.atomic():**,如下所示,对吗?

# "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):
        with transaction.atomic(): # Don't need
            super().save(*args, **kwargs)

或者,我们不需要将**'ATOMIC_REQUESTS': True设置为settings.py中的数据库设置**,如下图所示,右:

# "settings.py"

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

x759pob21#

默认情况下,transaction总是用于Django Admin,无论**save()是否被覆盖,覆盖的save()是否有super().save()以及覆盖的save()是否有@transaction.non_atomic_requests。我们不需要@transaction.atomicwith transaction.atomic():用于覆盖的save(),也不需要将'ATOMIC_REQUESTS': True设置为settings.py中的数据库设置**。我的答案解释了如何禁用事务用于Django管理员.
我试验了默认情况下,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

或者对于**,使用**super().save()@transaction.non_atomic_requests覆盖save(),如下所示:

# "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**:

然后,两个INSERT查询在**“开始”和“COMMIT”查询之间运行,如下所示。* 以下这些日志是PostgreSQL的查询日志**。您可以检查在PostgreSQL上,如何记录带有事务查询(如“BEGIN”和“COMMIT”)的SQL查询

接下来,将**John更新为Tom**:

然后,“开始”和“COMMIT”查询之间运行一个SELECTUPDATEINSERT查询,如下所示:

接下来,删除**Tom**:

然后,一个SELECTINSERTDELETE查询在**“开始”和“COMMIT”查询**之间运行,如下所示:

接下来,对于不带**super().save()但带@transaction.non_atomic_requests覆盖的save()**:

# "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没有被添加,因为overrided save()没有super().save()**:

然后,在**“开始”和“COMMIT”查询之间运行一个INSERT查询**,如下所示:

因此,正如上面的实验,我们可以看到,默认情况下,transaction总是用于Django Admin,无论**save()是否被覆盖,overrided save()是否有super().save()以及overrided save()是否有@transaction.non_atomic_requests。我们不需要对重写的save()使用@transaction.atomicwith transaction.atomic():
此外,对于
,用**super().save()@transaction.atomic重写了save(),如下所示:

# "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

或者,对于**,使用**super().save()with transaction.atomic():覆盖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
        
        with transaction.atomic(): # Here
            super().save(*args, **kwargs) # Here

我加上**John**:

然后,在**“开始”和“COMMIT”查询之间运行一个SAVEPOINTRELEASE SAVEPOINT查询以及两个INSERT查询**,如下所示:

接下来,对于**,使用**super().save()覆盖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设置为settings.py中的PostgreSQL设置**:

# "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**,如下所示:

然后,两个SELECTINSERT以及一个SAVEPOINTRELEASE SAVEPOINT“开始”和“提交”查询之间运行,如下所示:

接下来,对于被覆盖的**save(),我同时输入@transaction.atomicwith 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设置为settings.py中的PostgreSQL设置**,如下所示:

# "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**,如下所示:

然后,两个SELECTINSERT以及三个SAVEPOINTRELEASE SAVEPOINT“开始”和“提交”查询之间运行,如下所示:

相关问题