Пул соединений
Создавать физическое соединение на каждый запрос дорого
Открытие соединения с базой включает сетевое взаимодействие, аутентификацию и настройку сессии. Если серверное приложение будет создавать новое физическое соединение для каждого HTTP-запроса, оно потратит много времени и быстро упрётся в лимит подключений базы.
Пул соединений заранее держит ограниченный набор открытых соединений и выдаёт их приложению на короткое время.
Когда код вызывает close() у полученного из пула соединения,
обычно закрывается не физическое подключение к базе, а логическая обёртка возвращает ресурс обратно в пул.
Приложение обычно работает через DataSource
try (Connection connection = dataSource.getConnection()) {
try (PreparedStatement statement = connection.prepareStatement(
"SELECT name FROM users WHERE id = ?")) {
statement.setLong(1, 42);
// execute query
}
}
Интерфейс DataSource даёт приложению точку получения соединений.
Сам интерфейс не обязан быть пулом: конкретная реализация может выдавать обычные соединения,
а может быть связана с pooling-инфраструктурой. В типичном серверном приложении детали создания и переиспользования
соединений скрыты за настроенным DataSource.
Размер пула — это ограничение, а не способ открыть бесконечно много соединений
Если все соединения заняты, следующему запросу приходится ждать освобождения ресурса
или завершаться по тайм-ауту. Поэтому утечка одного Connection
в приложении с пулом особенно неприятна: со временем доступных соединений становится всё меньше.
close() сообщает пулу, что работа закончена и соединение можно выдать следующему запросу.
try-with-resources остаётся правильным способом организовать этот жизненный цикл.