Ricerca…


Transazioni atomiche

Problema

Per impostazione predefinita, Django commette immediatamente modifiche al database. Quando si verificano eccezioni durante una serie di commit, questo può lasciare il tuo database in uno stato indesiderato:

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

Nel seguente scenario:

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

Si verifica un'eccezione durante il tentativo di aggiungere il prodotto pantaloni alla categoria di abbigliamento. A questo punto, la categoria stessa è già stata aggiunta e il prodotto della maglietta è stato aggiunto.

La categoria incompleta e il prodotto contenente dovrebbero essere rimossi manualmente prima di correggere il codice e richiamare il metodo create_category() ancora una volta, altrimenti si creerebbe una categoria duplicata.


Soluzione

Il modulo django.db.transaction consente di combinare più modifiche al database in una transazione atomica :

[a] una serie di operazioni di database tali che si verificano tutte o non si verifica nulla.

Applicato allo scenario sopra, questo può essere applicato come decoratore :

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)

O utilizzando un gestore di contesto :

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)

Ora, se si verifica un'eccezione in qualsiasi fase della transazione, non verrà eseguito il commit delle modifiche al database.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow