Ответ
Функция transaction.on_commit()
в Django позволяет зарегистрировать колбэк (функцию), который будет выполнен только после успешного завершения (коммита) текущей транзакции в базе данных.
Это критически важно для выполнения действий, которые не должны происходить, если транзакция откатится. Основной сценарий использования — запуск фоновых задач, отправка уведомлений или вызов внешних API.
Почему это важно?
Представьте, что вы отправляете приветственное письмо сразу после создания пользователя. Если после отправки письма в транзакции произойдет ошибка и создание пользователя откатится, пользователь получит письмо, хотя его аккаунт не существует. on_commit
решает эту проблему.
Пример:
from django.db import transaction
from .tasks import send_welcome_email
def create_user_and_send_email(username, email):
# Начало транзакции (неявно, если ATOMIC_REQUESTS=True, или явно)
user = User.objects.create(username=username, email=email)
# Регистрируем задачу, которая выполнится только после коммита
transaction.on_commit(lambda: send_welcome_email.delay(user.id))
# ... другие операции в рамках транзакции
# Если здесь произойдет ошибка, on_commit() не будет вызван.
Ключевые особенности:
- Гарантия выполнения: Код выполняется только если транзакция успешно зафиксирована в БД.
- Изоляция: Позволяет отделить логику работы с БД от побочных эффектов (side effects).
- Тестирование: Для корректной работы в тестах требует использования
django.test.TestCase
, который оборачивает каждый тест в транзакцию.