Zoeken…


Atoomtransacties

Probleem

Standaard maakt Django onmiddellijk wijzigingen door in de database. Wanneer uitzonderingen optreden tijdens een reeks vastleggingen, kan uw database in een ongewenste staat achterblijven:

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

In het volgende scenario:

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

Een uitzondering doet zich voor wanneer wordt geprobeerd het broekproduct aan de kledingcategorie toe te voegen. Op dit punt is de categorie zelf al toegevoegd en is het shirtproduct eraan toegevoegd.

De onvolledige categorie en het product moeten handmatig worden verwijderd voordat de code wordt create_category() en de methode create_category() wordt create_category() , omdat anders een dubbele categorie wordt gemaakt.


Oplossing

Met de django.db.transaction module kunt u meerdere databasewijzigingen combineren in een atomaire transactie :

[a] reeks databasebewerkingen zodat ze allemaal voorkomen, of er gebeurt niets.

Toegepast op het bovenstaande scenario, kan dit worden toegepast als decorateur :

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)

Of door een contextmanager te gebruiken :

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)

Als er nu een uitzondering optreedt in een bepaald stadium van de transactie, worden er geen databasewijzigingen doorgevoerd.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow