原子交易
问题
默认情况下,Django 立即提交对数据库的更改。在一系列提交期间发生异常时,这可能会使你的数据库处于不需要的状态:
def create_category(name, products):
category = Category.objects.create(name=name)
product_api.add_products_to_category(category, products)
activate_category(category)
在以下场景中:
>>> create_category('clothing', ['shirt', 'trousers', 'tie'])ValueError: Product 'trousers' already exists
在尝试将裤子产品添加到服装类别时发生异常。到目前为止,已经添加了类别本身,并且已经添加了衬衫产品。
在修复代码并再次调用 create_category()
方法之前,必须手动删除不完整的类别和包含产品,否则将创建重复的类别。
解
django.db.transaction
模块允许你将多个数据库更改组合到原子事务中 :
[a]一系列数据库操作,使得全部发生或不发生任何事情。
应用于上述场景,这可以作为装饰器应用 :
from django.db import transaction
@transaction.atomic
def create_category(name, products):
category = Category.objects.create(name=name)
product_api.add_products_to_category(category, products)
activate_category(category)
或者使用上下文管理器 :
def create_category(name, products):
with transaction.atomic():
category = Category.objects.create(name=name)
product_api.add_products_to_category(category, products)
activate_category(category)
现在,如果在事务中的任何阶段发生异常,则不会提交任何数据库更改。