Что такое вложенные транзакции (subtransactions) в Django и для чего они используются?

Ответ

Вложенная транзакция (subtransaction) в Django — это точка сохранения (savepoint) внутри основной транзакции, управляемая через контекстный менеджер transaction.atomic().

Ключевое отличие: откат вложенной транзакции (например, из-за исключения) не отменяет всю родительскую транзакцию. Он лишь возвращает состояние базы данных к моменту входа во вложенный блок.

Пример:

from django.db import transaction

# Основная транзакция
with transaction.atomic():
    # ... какие-то успешные операции в БД ...

    try:
        # Вложенная транзакция (subtransaction)
        with transaction.atomic():
            # Код, который может вызвать ошибку
            Order.objects.create(status='invalid_data') # Пример операции
            raise ValueError("Ошибка во вложенной транзакции")
    except ValueError:
        # Операции внутри вложенного блока 'atomic' будут отменены,
        # но основная транзакция продолжится.
        print("Вложенная транзакция откатилась.")

    # Этот объект будет успешно сохранен, так как основная транзакция не прервалась
    Product.objects.create(name='Final Product')

Основные сценарии использования:

  • Изоляция части операций: Когда нужно гарантировать атомарность небольшого блока кода, не рискуя всей транзакцией при его сбое.
  • Обработка данных с частичным успехом: Например, при импорте данных из файла, где ошибка в одной строке не должна отменять импорт всех предыдущих корректных строк.