-
原子性是数据库事务的定义属性。
atomic
允许我们创建一个代码块,在其中保证数据库的原子性。如果代码块成功完成,则将更改提交到数据库。如果出现异常,则回滚更改。atomic
块可以嵌套。在这种情况下,当一个内部块成功完成时,如果稍后在外部块中引发异常,它的效果仍然可以回滚。确保
atomic
块始终是最外层的atomic
块有时很有用,以确保在退出块时提交任何数据库更改而没有错误。这称为持久性,可以通过设置durable=True
来实现。如果atomic
块嵌套在另一个块中,则会引发RuntimeError
。atomic
既可用作装饰器:from django.db import transaction @transaction.atomic def viewfunc(request): # This code executes inside a transaction. do_stuff()
并作为上下文管理器:
from django.db import transaction def viewfunc(request): # This code executes in autocommit mode (Django's default). do_stuff() with transaction.atomic(): # This code executes inside a transaction. do_more_stuff()
在 try/except 块中包装
atomic
允许自然处理完整性错误:from django.db import IntegrityError, transaction @transaction.atomic def viewfunc(request): create_parent() try: with transaction.atomic(): generate_relationships() except IntegrityError: handle_exception() add_children()
在此示例中,即使
generate_relationships()
通过破坏完整性约束导致数据库错误,您也可以在add_children()
中执行查询,并且来自create_parent()
的更改仍然存在并绑定到同一个事务。请注意,在调用handle_exception()
时,在generate_relationships()
中尝试的任何操作都已经安全回滚,因此异常处理程序也可以在必要时对数据库进行操作。避免在
atomic
中捕获异常!当退出
atomic
块时,Django 会查看它是正常退出还是异常退出,以确定是提交还是回滚。如果您在atomic
块中捕获并处理异常,您可能会向 Django 隐藏已发生问题的事实。这可能会导致意外行为。这主要是
DatabaseError
IntegrityError
atomic
块的末尾执行回滚。如果您尝试在回滚发生之前运行数据库查询,Django 将引发TransactionManagementError
捕获数据库错误的正确方法是围绕
atomic
块,如上所示。如有必要,为此添加一个额外的atomic
块。这种模式还有另一个优点:它明确界定了如果发生异常,哪些操作将被回滚。如果您捕获原始 SQL 查询引发的异常,则 Django 的行为是未指定的并且database-dependent。
回滚事务时,您可能需要手动恢复模型状态。
当事务回滚发生时,模型字段的值不会被恢复。除非您手动恢复原始字段值,否则这可能会导致模型状态不一致。
例如,给定带有
active
字段的MyModel
,如果在事务中将active
更新为True
失败,则此代码段可确保最后的if obj.active
检查使用正确的值:from django.db import DatabaseError, transaction obj = MyModel(active=False) obj.active = True try: with transaction.atomic(): obj.save() except DatabaseError: obj.active = False if obj.active: ...
为了保证原子性,
atomic
禁用了一些 API。尝试在atomic
块内提交、回滚或更改数据库连接的自动提交状态将引发异常。atomic
采用using
参数,该参数应该是数据库的名称。如果没有提供这个参数,Django 使用"default"
数据库。在底层,Django 的事务管理代码:
- 进入最外层
atomic
块时打开一个事务; - 进入内部
atomic
块时创建保存点; - 退出内部块时释放或回滚到保存点;
- 退出最外层块时提交或回滚事务。
您可以通过将
savepoint
参数设置为False
来禁用为内部块创建保存点。如果发生异常,Django 将在退出第一个带有保存点的父块时执行回滚,如果有,则退出最外层的块。原子性仍然由外部事务保证。仅当保存点的开销很明显时才应使用此选项。它的缺点是破坏了上述错误处理。当自动提交关闭时,您可以使用
atomic
。它只会使用保存点,即使是最外面的块。 - 进入最外层
本文介绍 django.db.transaction.atomic
的用法。
声明
atomic(using=None, savepoint=True, durable=False)[source]
相关用法
- Python attr.asdict()用法及代码示例
- Python arcgis.gis._impl._profile.ProfileManager.save_as用法及代码示例
- Python arcgis.raster.functions.ccdc_analysis用法及代码示例
- Python arcgis.geometry.functions.trim_extend用法及代码示例
- Python arcgis.raster.analytics.sample用法及代码示例
- Python arcgis.features.analysis.derive_new_locations用法及代码示例
- Python arcgis.features.analyze_patterns.calculate_density用法及代码示例
- Python arcgis.geometry.Geometry.label_point用法及代码示例
- Python ast.MatchClass用法及代码示例
- Python arcgis.plan_routes用法及代码示例
- Python arcgis.mapping.forms.FormInfo用法及代码示例
- Python arcgis.gis.UserManager.get用法及代码示例
- Python arcgis.raster.ImageryLayerCacheManager.update_tiles用法及代码示例
- Python arcgis.geometry.Geometry.true_centroid用法及代码示例
- Python arcgis.gis.User.generate_direct_access_url用法及代码示例
- Python arcgis.gis.GroupMigrationManager.create用法及代码示例
- Python arcgis.geometry.Geometry.hull_rectangle用法及代码示例
- Python arcgis.features.analysis.summarize_within用法及代码示例
- Python arcgis.geometry.filters.intersects用法及代码示例
- Python arcgis.geometry.functions.project用法及代码示例
- Python abc.ABCMeta用法及代码示例
- Python arcgis.raster.functions.percentile用法及代码示例
- Python arcgis.raster.ImageryLayer.save用法及代码示例
- Python arcgis.geoanalytics.summarize_data.reconstruct_tracks用法及代码示例
- Python arcgis.gis.admin.LivingAtlas用法及代码示例
注:本文由纯净天空筛选整理自djangoproject.com大神的英文原创作品 django.db.transaction.atomic。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。