select_for_update удерживает блокировку строки ProviderOrder до конца transaction.atomic. Опасность зависит от того, делают ли unblock_provider_order и notify_contractor внешние вызовы.
with transaction.atomic():
select_for_update удерживает блокировку строки ProviderOrder до конца transaction.atomic. Опасность зависит от того, делают ли unblock_provider_order и notify_contractor внешние вызовы.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
with transaction.atomic(): provider_order = ProviderOrder.objects.select_for_update().get(id=provider_order.id) unblock_provider_order(provider_order.id) notify_contractor(provider_order=provider_order)
Ответ
select_for_update удерживает блокировку строки ProviderOrder до конца transaction.atomic. Опасность зависит от того, делают ли unblock_provider_order и notify_contractor внешние вызовы.
Если уведомление отправляется до commit, адресат может получить событие о данных, которые позже откатятся. Долгая сеть внутри транзакции также продлевает блокировку и увеличивает конкуренцию.
Оставьте изменение данных в короткой транзакции, а внешнее уведомление запускайте после успешного commit. transaction.on_commit устраняет отправку при rollback, но не закрывает падение процесса между commit и отправкой; для надёжности нужен outbox. Неизвестные тела функций нельзя объявлять ошибочными без проверки. При повторной блокировке соблюдайте общий порядок ресурсов.