Suche…


Atomare Transaktionen

Problem

Standardmäßig übernimmt Django sofort Änderungen an der Datenbank. Wenn während einer Reihe von Commits Ausnahmen auftreten, kann dies dazu führen, dass Ihre Datenbank in einem unerwünschten Zustand bleibt:

def create_category(name, products):
    category = Category.objects.create(name=name)
    product_api.add_products_to_category(category, products)
    activate_category(category)

Im folgenden Szenario:

>>> create_category('clothing', ['shirt', 'trousers', 'tie'])
---------------------------------------------------------------------------
ValueError: Product 'trousers' already exists

Eine Ausnahme tritt auf, wenn versucht wird, das Hosenprodukt der Bekleidungskategorie hinzuzufügen. Zu diesem Zeitpunkt wurde die Kategorie selbst bereits hinzugefügt und das Shirt-Produkt wurde hinzugefügt.

Die unvollständige Kategorie und das enthaltende Produkt müssten manuell entfernt werden, bevor der Code create_category() und die Methode create_category() erneut create_category() , da andernfalls eine doppelte Kategorie erstellt wird.


Lösung

Mit django.db.transaction Modul django.db.transaction können Sie mehrere Datenbankänderungen in einer atomaren Transaktion kombinieren:

[a] Reihe von Datenbankoperationen, bei denen entweder alle auftreten oder nichts auftritt.

Auf das obige Szenario angewendet, kann dies als Dekorateur angewendet werden:

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)

Oder mit einem Kontextmanager :

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)

Wenn jetzt in einer beliebigen Phase der Transaktion eine Ausnahme auftritt, werden keine Datenbankänderungen festgeschrieben.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow