原子交易

問題

預設情況下,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)

現在,如果在事務中的任何階段發生異常,則不會提交任何資料庫更改。