Как правильно использовать transaction.on_commit с задачами Celery в Django?

Подход 1: Без transaction.atomic

Источник: https://adamj.eu/tech/2022/08/22/use-partial-with-djangos-transaction-on-commit/
def order_created(order):
    order.status = 'created'
    order.save()
    transaction.on_commit(
        partial(send_order_email.delay, order_id=order.id)
    )

Подход 2: С transaction.atomic

def order_created(order):
    with transaction.atomic():
        order.status = 'created'
        order.save()
        transaction.on_commit(
            partial(send_order_email.delay, order_id=order.id)
        )

Какой подход является правильным и почему? Операция save() вносит изменения в базу данных, но примеры расходятся в том, нужна ли операция transaction.atomic. (ATOMIC_REQUESTS=False в настройках)

В первом примере transaction.on_commit приведет к ошибке, если нет открытой транзакции ( связанная документация), плюс save() будет выполнен сразу, так что on_commit вообще не нужен.

Во втором примере задача Celery будет поставлена в очередь в конце успешной транзакции. Насколько я понимаю ваш вопрос, это ожидаемое поведение

Вернуться на верх