Django
Transactions de base de données
Recherche…
Transactions atomiques
Problème
Par défaut, Django valide immédiatement les modifications apportées à la base de données. Lorsque des exceptions se produisent pendant une série de validations, cela peut laisser votre base de données dans un état indésirable:
def create_category(name, products):
category = Category.objects.create(name=name)
product_api.add_products_to_category(category, products)
activate_category(category)
Dans le scénario suivant:
>>> create_category('clothing', ['shirt', 'trousers', 'tie'])
---------------------------------------------------------------------------
ValueError: Product 'trousers' already exists
Une exception se produit lors de la tentative d’ajout du produit pantalon à la catégorie des vêtements. À ce stade, la catégorie elle-même a déjà été ajoutée et le produit de la chemise a été ajouté.
La catégorie incomplète et le produit contenant doivent être supprimés manuellement avant de corriger le code et d'appeler à nouveau la méthode create_category()
, sinon une catégorie de doublons serait créée.
Solution
Le module django.db.transaction
vous permet de combiner plusieurs modifications de base de données en une transaction atomique :
[une] série d'opérations de base de données telles que toutes se produisent ou rien ne se produit.
Appliqué au scénario ci-dessus, il peut être appliqué en tant que décorateur :
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)
Ou en utilisant un gestionnaire de contexte :
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)
Maintenant, si une exception se produit à n'importe quelle étape de la transaction, aucune modification de base de données ne sera validée.