原子交易

问题

默认情况下,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)

现在,如果在事务中的任何阶段发生异常,则不会提交任何数据库更改。