По умолчанию Spring забирает connection в момент открытия транзакции, а не в момент первого SQL-запроса.
Проблема в том, что иногда запросов может не быть вообще.
Типичный сценарий в Enterprise:
— cache hit;
— ранний return;
— не прошла валидация;
— проверка прав завернула вызов;
— сначала сходили в медленный внешний API, а до БД еще даже не дошли.
Но connection уже вынули из пула. Он просто лежит занятым, пока метод делает что угодно, кроме работы с базой.
Конечно, открывать транзакцию там, где она может не понадобиться - далеко не самый оптимальный вариант. В идеале такого не допускать вообще.
Тем не менее, стоит признать, что такое часто встречается. В Spring Boot 4.1 эта проблема чинится одной property:
spring.datasource.connection-fetch=lazy
Смысл такой, что нет SQL — нет connection. То есть раньше приложение брало connection на всякий случай. А теперь только когда он реально нужен.
⚠️ Обратите внимание, что данная настройка работает не только с Hibernate. Более того, вообще любая блокирующая технология доступа к БД в экосистеме Spring (
JdbcClient, Spring Data JDBC и т.д.) может работать с этой фичей.Происходит это потому, что под капотом используется
LazyConnectionDataSourceProxy, который, на самом деле, существует давно. Просто раньше надо было знать о нем, лезть в конфиг и руками оборачивать DataSource.В итоге, где это реально имеет смысл:
— широкие
@Transactional границы;— early-return без похода в БД;
— нагрузка, где каждый idle connection уже начинает стоить дорого.
Флаг довольно удобный. Имейте в виду!