Ответ
В 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()
# ... остальной код ...