我检查了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
}
}
1条答案
按热度按时间x759pob21#
默认情况下,transaction总是用于Django Admin,无论**
save()
是否被覆盖,覆盖的save()
是否有super().save()
以及覆盖的save()
是否有@transaction.non_atomic_requests
。我们不需要@transaction.atomic
或with transaction.atomic():
用于覆盖的save()
,也不需要将'ATOMIC_REQUESTS': True
设置为settings.py
中的数据库设置**。我的答案解释了如何禁用事务用于Django管理员.我试验了默认情况下,transaction是否总是用于Django Admin。我使用了PostgreSQL。 您也可以看到我的答案,它试验了Atomic Transaction是否用于Django View默认情况下:
对于未覆盖的
save()
,如下所示:或者对于**,使用**
super().save()
和@transaction.non_atomic_requests
覆盖save()
,如下所示:我加上**
John
**:然后,两个
INSERT
查询在**“开始”和“COMMIT”查询之间运行,如下所示。* 以下这些日志是PostgreSQL的查询日志**。您可以检查在PostgreSQL上,如何记录带有事务查询(如“BEGIN”和“COMMIT”)的SQL查询:接下来,将**
John
更新为Tom
**:然后,在“开始”和“COMMIT”查询之间运行一个
SELECT
、UPDATE
和INSERT
查询,如下所示:接下来,删除**
Tom
**:然后,一个
SELECT
、INSERT
和DELETE
查询在**“开始”和“COMMIT”查询**之间运行,如下所示:接下来,对于不带**
super().save()
但带@transaction.non_atomic_requests
的覆盖的save()
**:我添加了**
John
。* 实际上,John
没有被添加,因为overridedsave()
没有super().save()
**:然后,在**“开始”和“COMMIT”查询之间运行一个
INSERT
查询**,如下所示:因此,正如上面的实验,我们可以看到,默认情况下,transaction总是用于Django Admin,无论**
save()
是否被覆盖,overridedsave()
是否有super().save()
以及overridedsave()
是否有@transaction.non_atomic_requests
。我们不需要对重写的save()
使用@transaction.atomic
或with transaction.atomic():
。此外,对于,用**
super().save()
和@transaction.atomic
重写了save()
,如下所示:或者,对于**,使用**
super().save()
和with transaction.atomic():
覆盖save()
,如下所示:我加上**
John
**:然后,在**“开始”和“COMMIT”查询之间运行一个
SAVEPOINT
和RELEASE SAVEPOINT
查询以及两个INSERT
查询**,如下所示:接下来,对于**,使用**
super().save()
覆盖save()
,如下所示:我将**
'ATOMIC_REQUESTS': True
设置为settings.py
中的PostgreSQL设置**:然后,添加**
John
**,如下所示:然后,两个
SELECT
和INSERT
以及一个SAVEPOINT
和RELEASE SAVEPOINT
在“开始”和“提交”查询之间运行,如下所示:接下来,对于被覆盖的**
save()
,我同时输入@transaction.atomic
和with transaction.atomic():
**,如下所示:并且,我还将**
'ATOMIC_REQUESTS': True
设置为settings.py
中的PostgreSQL设置**,如下所示:然后,添加**
John
**,如下所示:然后,两个
SELECT
和INSERT
以及三个SAVEPOINT
和RELEASE SAVEPOINT
在“开始”和“提交”查询之间运行,如下所示: