Что такое соединение в JDBC?

Что такое объект соединения в JDBC? Как поддерживается это соединение (я имею в виду, это сетевое соединение)? Являются ли они соединениями TCP/IP? Почему создание Connection каждый раз является дорогостоящей операцией? Почему через какое-то время эти соединения устаревают, и мне нужно обновить пул? Почему я не могу использовать одно соединение для выполнения нескольких запросов?


person Geek    schedule 08.05.2009    source источник


Ответы (4)


Эти соединения являются соединениями TCP/IP. Чтобы не создавать каждый раз новое соединение, существуют пулы соединений, которые динамически расширяются и сжимаются. Вы можете использовать одно соединение для нескольких запросов. Я думаю, вы имеете в виду, что вы выпускаете его в пул. Если вы сделаете это, вы можете получить то же соединение из пула. В этом случае просто не имеет значения, делаете ли вы один или несколько запросов.

Стоимость соединения заключается в подключении, которое занимает некоторое время. И база данных готовит некоторые вещи, такие как сеансы и т. Д., Для каждого соединения. Это нужно было бы делать каждый раз. Соединения устаревают по нескольким причинам. Наиболее заметным из них является брандмауэр между ними. Проблемы с подключением могут привести к сбросу подключения или простому тайм-ауту.

person Norbert Hartl    schedule 08.05.2009
comment
Спасибо, Норберт. Мой вопрос заключался в том, могу ли я одновременно запускать два или более запросов к объекту One Connection? - person Geek; 08.05.2009
comment
Точно не знаю, но я бы попробовал. Если вы отправляете запрос, вы получаете дескриптор для вашего набора результатов. Так что теоретически нет особых причин, по которым это не должно работать. Может быть, это отличается между базами данных, но с более крупными я бы не ожидал, что это будет проблемой. - person Norbert Hartl; 08.05.2009
comment
Норберт Я думаю, что мы не можем выполнять два запроса по одному и тому же соединению. Могут быть проблемы с синхронизацией. Я тоже не уверен, но по логике, если бы вы могли это сделать, вам бы никогда не понадобился пул. Одного подключения будет достаточно. - person Geek; 08.05.2009
comment
Вы, конечно, можете это сделать, единственное, что нужно помнить, это то, что вы будете использовать одни и те же свойства соединения и один и тот же сеанс между запросами. Возможно, будет использоваться одна и та же транзакция, если иным образом не будет зафиксировано или отменено каким-либо образом. - person Adeel Ansari; 08.05.2009
comment
Кроме того, позвольте мне прояснить и это. Когда вы отправляете соединение обратно в пул, API сбрасывает состояние этого соединения как только что созданное. Например, вы могли изменить setAutoCommit(), но когда вы отправляете его обратно в пул, базовая библиотека пула вернет значение по умолчанию. - person Adeel Ansari; 08.05.2009
comment
@Geek Вам все равно понадобится пул, потому что создание простого соединения на самом деле довольно сложно. Таким образом, вы сохраняете и повторно используете соединения TCP/IP и уже установленное соединение внутри базы данных. Это основная проблема, связанная с наличием бассейна. При совместном использовании пула среднее необходимое соединение имеет минимально возможное значение. Таким образом, вам может потребоваться не более 3 подключений на веб-сервер. Это снижает общее количество подключений к базе данных, что является большим ускорением. - person Norbert Hartl; 08.05.2009
comment
@Geek Я забыл добавить, что при таком сценарии вы все ускоряете, если держите соединение только тогда, когда оно вам нужно. Чем средний будет ниже. Подумайте о том, чтобы не получать соединение в начале метода, но сначала подготовьте все, чем получить соединение, отправить запрос и вернуть соединение как можно раньше. - person Norbert Hartl; 08.05.2009

Чтобы добавить к другим ответам:

Да, вы можете повторно использовать одно и то же соединение для нескольких запросов. Это даже целесообразно, так как создание нового соединения довольно затратно.

Вы даже можете выполнять несколько запросов одновременно. Вам просто нужно использовать новый экземпляр java.sql.Statement/PreparedStatement для каждого запроса. Операторы — это то, что JDBC использует для отслеживания текущих запросов, поэтому для каждого параллельного запроса требуется свой собственный оператор. Однако вы можете и должны повторно использовать операторы для последовательных запросов.

person sleske    schedule 08.05.2009
comment
Что вы имеете в виду под своим последним утверждением? Мы можем повторно использовать только переменную, а не объект оператора, как мы обычно делаем con.createStatement() или con.prepareStatement(). И я считаю, что это дает вам новый экземпляр каждый раз. - person Adeel Ansari; 08.05.2009
comment
Да, con.createStatement() каждый раз создает новый экземпляр. Но вы можете многократно использовать его для выполнения операторов, например: stmt.execute(my sql 1); stmt.getResultSet; // делаем что-то с ResultSet; stmt.execute(my sql 2)... Но вы не должны использовать ResultSet после повторного использования его оператора, b/c, тогда ResultSet будет сброшен. - person sleske; 09.05.2009

Ответы на ваши вопросы заключаются в том, что они определяются реализацией. Соединение JDBC — это интерфейс, предоставляющий методы. То, что происходит за кулисами, может быть чем угодно, что обеспечивает интерфейс. Например, рассмотрим внутренний драйвер JDBC Oracle, используемый для поддержки хранимых процедур Java. Одновременные запросы не только возможны, они более или менее неизбежны, так как каждый запрос на новое соединение возвращает один и тот же объект соединения. Я не знаю точно, использует ли он TCP/IP внутри, но я сомневаюсь в этом.

Таким образом, вы не должны брать на себя детали реализации, не зная точно, какую именно реализацию JDBC вы используете.

person Alohci    schedule 08.05.2009
comment
Для драйвера Oracle JDBC используйте протокол TCP/IP, который эмулирует Oracle Net8. Я надеюсь, что это делает вещь ясной. - person Adeel Ansari; 08.05.2009

поскольку я еще не могу комментировать, опубликую ответ только для того, чтобы прокомментировать ответ Vinegar, ситуация с возвратом setAutoCommit() в состояние по умолчанию после возврата соединения с пулом не является обязательным поведением и не должна восприниматься как должное, также как закрытие операторов и наборов результатов; вы можете прочитать, что он должен быть закрыт, но если вы их не закроете, они будут автоматически закрыты с закрытием соединения. Не принимайте это как должное, так как это потребует ваших ресурсов в некоторых версиях драйверов jdbc.

У нас была серьезная проблема с базой данных DB2 на AS400, ребята, нуждающиеся в изоляции транзакций, вызывали connection.setAutoCommit(false) и после завершения работы возвращали такое соединение в пул (JNDI) без connection.setAutoCommit(old_state), поэтому, когда другой поток получил это соединение из пула вставки и обновления не совершались, и долго никто не мог понять почему...

person ante.sabo    schedule 08.05.2009