Как в Django правильно запустить асинхронную Celery-задачу внутри блока транзакции Atomic? Например, рассылку email.

Поставьте отправку Celery-задачи в transaction.on_commit, чтобы она запускалась только после успешного commit. При rollback callback не выполняется, и worker не увидит незаписанные данные.

Короткий ответ

Что ответить на собеседовании

Поставьте отправку Celery-задачи в transaction.on_commit, чтобы она запускалась только после успешного commit. При rollback callback не выполняется, и worker не увидит незаписанные данные.

Подробный разбор

Ответ с пояснениями

Поставьте отправку Celery-задачи в transaction.on_commit, чтобы она запускалась только после успешного commit. При rollback callback не выполняется, и worker не увидит незаписанные данные.

from django.db import transaction

with transaction.atomic():
    record = create_record()
    transaction.on_commit(lambda: send_email.delay(record.pk))

create_record и send_email здесь обозначают функции приложения. В цикле фиксируйте ID в аргументе lambda или partial. Между commit и публикацией в брокер возможен сбой процесса: для гарантированной доставки нужен transactional outbox. Повторная отправка задачи должна быть безопасной.

Источник: docs.celeryq.dev.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее