Django
Datenbanktransaktionen
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.