Пул соединений JDBC: повторное использование соединения?
Насколько я понимаю, пул соединений JDBC (на базовом уровне) работает следующим образом:
- создавать соединения во время инициализации приложения и помещать в кеш
- предоставить эти кэшированные соединения по требованию к приложению
- отдельный поток поддерживает пул соединений, выполняя такие действия, как:
- отменить соединения, которые были использованы (закрыты)
- создавать новые соединения и добавлять в кеш для поддержания определенного количества соединений
Но всякий раз, когда я слышу термин "повторное использование соединения" в обсуждении JDBC Connection Pooling, я запутываюсь. Когда происходит повторное использование соединения?
Означает ли это, что пул соединений обеспечивает одно и то же соединение для двух разных взаимодействий с базой данных (не закрывая его)? Или есть способ продолжить использование соединения даже после его закрытия после вызова БД?
4 ответа
Пул соединений работает путем повторного использования соединений. Приложения "заимствуют" соединение из пула, а затем "возвращают" его по завершении. Затем соединение снова передается другой части приложения или даже другому приложению.
Это совершенно безопасно, если одно и то же соединение не используется двумя потоками одновременно.
Ключевым моментом при создании пула соединений является недопущение создания новых соединений, где это возможно, поскольку обычно это дорогостоящая операция. Повторное использование соединений имеет решающее значение для производительности.
Пул соединений не предоставляет вам фактический экземпляр Connection от драйвера, но возвращает оболочку. Когда вы вызываете метод close() для экземпляра Connection из пула, он не закрывает соединение драйвера, а просто возвращает открытое соединение в пул, чтобы его можно было повторно использовать (см. Ответ skaffman).
Пул соединений повторно использует соединения. Вот как работает apache dbcp.
Connection poolableConnection= apacheDbcpDataSource.getConnection();
Реализация Apache DBCP возвращает оболочку подключения, которая имеет тип PoolableConnection.
poolableConnection.close();
PoolableConnection.close () проверяет, закрыто или нет фактическое базовое соединение, если нет, то возвращает этот экземпляр PoolableConnection в пул соединений (в данном случаеGenericObjectPool).
if (!isUnderlyingConectionClosed) {
// Normal close: underlying connection is still open, so we
// simply need to return this proxy to the pool
try {
genericObjectPool.returnObject(this); //this is PoolableConnection instance in this case
....
}
Мое понимание такое же, как указано выше, и, благодаря ошибке, у меня есть доказательства того, что это правильно. В приложении, с которым я работаю, была ошибка, команда SQL с недопустимым именем столбца. При исполнении выдается исключение. Если соединение закрыто, то в следующий раз, когда соединение получено и используется, на этот раз с правильным SQL, снова возникает исключение, и сообщение об ошибке совпадает с первым разом, хотя неправильное имя столбца даже не появляется в второй SQL. Таким образом, связь, очевидно, используется повторно. Если соединение не закрывается после выдачи первого исключения (из-за неверного имени столбца), то при следующем использовании соединения все будет работать нормально. Предположительно, это связано с тем, что первое соединение не было возвращено в пул для повторного использования. (Эта ошибка возникает в Jave 1.6_30 и при подключении к базе данных MySQL.)