С какими ORM вы работали и как выполняли синхронные запросы
Что проверяют
Вопрос звучит как про опыт, а проверяет понимание того, как код, блокирующий поток на обращении к базе, уживается с асинхронным приложением. Уточнение про синхронность почти всегда означает, что в проекте есть асинхронный веб-фреймворк и связанные с ним грабли.
Как отвечать
Сначала коротко о том, с чем работали и где это было уместно, дальше механика. Блокирующий запрос занимает поток на всё время ожидания ответа базы. В потоковом сервере это нормально, каждое обращение и так живёт в своём потоке. В цикле событий это остановка всего процесса: пока драйвер ждёт сокет, не обслуживается ни один другой клиент.
Отсюда три рабочих варианта:
- оставить блокирующую библиотеку и уводить вызовы в пул потоков, в Django для этого есть штатная обёртка, а сам слой доступа к данным бросает исключение, если позвать его из цикла событий напрямую;
- взять асинхронный движок и асинхронную сессию, тогда и драйвер должен быть асинхронным;
- держать работу с базой в отдельном воркере или синхронном сервисе.
Добавьте про транзакции и соединения: явная граница транзакции вместо фиксации на каждом запросе, время жизни соединения, осторожность с подготовленными выражениями при внешнем пуле соединений.
Где спотыкаются
Отвечают списком библиотек и не замечают вторую половину вопроса. Дальше следует уточнение про блокировку цикла событий, и заготовленный рассказ рассыпается.
Вторая ошибка: считать, что обёртка над блокирующим вызовом делает его асинхронным. Она переносит работу в поток, а значит потолок параллельности определяется размером пула и лимитом соединений к базе.
Третья: ленивая подгрузка связей внутри асинхронного обработчика. Обращение к связанному объекту превращается в скрытый запрос, в асинхронной сессии это прямая ошибка, а в блокирующем коде просто множит походы в базу внутри цикла.