Поиск…


Атомные транзакции

проблема

По умолчанию Django немедленно вносит изменения в базу данных. Когда исключения происходят во время серии коммитов, это может оставить вашу базу данных в нежелательном состоянии:

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

В следующем сценарии:

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

Исключение возникает при попытке добавить продукт брюк в категорию одежды. К этому моменту уже добавлена ​​сама категория, и к ней добавлен продукт рубашки.

Неполную категорию и содержащий продукт нужно удалить вручную до исправления кода и вызова create_category() еще раз, так как в противном случае будет создана повторяющаяся категория.


Решение

Модуль django.db.transaction позволяет объединять несколько изменений базы данных в атомную транзакцию :

[a] ряд операций с базой данных, в которых либо все происходит, либо ничего не происходит.

Применительно к описанному выше сценарию это можно применить в качестве декоратора :

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)

Или с помощью диспетчера контекстов :

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)

Теперь, если исключение происходит на любом этапе транзакции, никаких изменений базы данных не будет.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow