サーチ…


アトミックトランザクション

問題

デフォルトでは、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)

現在、トランザクション内のどの段階でも例外が発生すると、データベースの変更はコミットされません。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow