-
原子性是数据库事务的定义属性。
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)的问题。在这样的错误之后,事务被破坏,Django 将在IntegrityErroratomic块的末尾执行回滚。如果您尝试在回滚发生之前运行数据库查询,Django 将引发。当ORM-related 信号处理程序引发异常时,您也可能会遇到此行为。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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。
