默认情况下Django Admin是否已使用事务?代码验证与相关疑问
关于Django Admin默认事务及Model.save()的事务处理问题
一、Django Model底层的事务处理逻辑
从Django源码的Model类实现中可以看到,save()方法会调用save_base(),而save_base()内部会根据模型是否有父类(继承关系)自动处理事务:
# 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, ): # ... # 仅当需要执行多个查询时才需要事务 if meta.parents: context_manager = transaction.atomic(using=using, savepoint=False) else: context_manager = transaction.mark_for_rollback_on_error(using=using) with context_manager: # 执行具体的保存逻辑 # ...
这两个上下文管理器的作用:
transaction.atomic:开启原子事务,确保所有操作要么全部提交,要么全部回滚;关闭savepoint是因为不需要嵌套保存点transaction.mark_for_rollback_on_error:若代码块执行抛出异常,标记当前事务需回滚,若已有事务则直接复用
二、默认情况下Django Admin是否使用事务?
是的。Django Admin处理模型创建、修改操作时,最终都会调用Model的save()方法,自然会触发save_base()中的事务逻辑。此外Admin视图在批量操作等场景也会额外处理事务,但单模型的核心保存逻辑已经由Model层的事务覆盖。
三、重写Model.save()时的事务疑问解答
1. 无需额外添加@transaction.atomic装饰器
当你重写save()并调用super().save(*args, **kwargs)时,父类save()已经通过save_base()处理了事务,不需要再给自定义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 # 无需添加 def save(self, *args, **kwargs): 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)
2. 无需额外使用with transaction.atomic():上下文管理器
同理,父类save()已经包含事务处理,不需要在自定义save()里嵌套事务上下文:
不必要的写法:
# 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(): # 无需添加 super().save(*args, **kwargs)
3. 无需强制设置ATOMIC_REQUESTS = True
ATOMIC_REQUESTS = True的作用是让每个HTTP请求都包裹在原子事务中,确保整个请求的所有数据库操作要么全提交、要么全回滚。但单模型保存的事务已经由Model层处理,不需要为这个场景特意开启该配置。
当然,如果业务需要整个请求的多模型操作、关联操作都在一个事务内,开启ATOMIC_REQUESTS是合理的,但这不是单模型保存的必要条件。
不必要的配置示例:
# settings.py DATABASES = { 'default':{ 'ENGINE':'django.db.backends.postgresql', 'NAME':'postgres', 'USER':'postgres', 'PASSWORD':'admin', 'HOST':'localhost', 'PORT':'5432', 'ATOMIC_REQUESTS': True, # 单模型保存无需强制开启 } }
内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito
相关产品推荐
相关产品推荐

