Django
Transazioni di database
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.