Как управлять транзакциями в Django?

Ответ

В Django для управления транзакциями используется django.db.transaction.atomic. Этот инструмент гарантирует, что блок кода будет выполнен в рамках одной транзакции базы данных, обеспечивая атомарность операций.

По умолчанию Django работает в режиме autocommit, где каждый ORM-запрос (.save(), .delete(), .update()) выполняется в своей отдельной транзакции. transaction.atomic необходим, чтобы объединить несколько таких запросов в одну неделимую операцию.

transaction.atomic можно использовать двумя способами:

1. Как декоратор для функции или метода:

Весь код функции будет обернут в одну транзакцию. Если функция завершится без исключений, транзакция будет зафиксирована (COMMIT). При возникновении исключения — отменена (ROLLBACK).

from django.db import transaction

@transaction.atomic
def transfer_funds(sender, receiver, amount):
    # Эти две операции будут выполнены атомарно
    sender.balance -= amount
    sender.save()

    # Если здесь произойдет ошибка, то sender.save() будет отменен
    receiver.balance += amount
    receiver.save()

2. Как менеджер контекста (с помощью with):

Это позволяет применять транзакционную логику к определенному блоку кода, а не ко всей функции.

from django.db import transaction

def some_view(request):
    # ... какой-то код ...

    try:
        with transaction.atomic():
            # Код внутри этого блока выполняется в транзакции
            order = Order.objects.create(user=request.user, status='processing')
            OrderItem.objects.create(order=order, product=product, quantity=2)
    except IntegrityError:
        # Обработка ошибки, если что-то пошло не так
        handle_error()

    # ... остальной код ...