Пока банк отвечает на запрос оплаты, остальные операции с заказом висят
async with session.begin():
order = await session.get(Order, order_id, with_for_update=True)
result = await bank_client.charge(order.total) # 5–30 секунд
order.status = "paid" if result.ok else "failed"
Когда банк отвечает медленно, запросы на изменение этого заказа и отчёты, которые его обновляют, ждут десятки секунд, а в pg_stat_activity висят сессии в состоянии idle in transaction. В чём проблема?
- Транзакция с блокировкой строки открыта всё время ожидания внешнего API
- with_for_update блокирует всю таблицу заказов, а не одну строку
- Асинхронная сессия SQLAlchemy не освобождает соединение до конца запроса
- Банк сам блокирует заказ на своей стороне на время списания
