Когда закрывать Connection, Statement, PreparedStatement и ResultSet в JDBC - PullRequest
29 голосов
/ 24 июня 2009

Несколько вопросов по кодированию JDBC:

  1. Для одного клиентского приложения нужен ли нам пул подключений?
  2. Является ли хорошей идеей создать соединение в начале и поддерживать его без закрытия до закрытия приложения? Почему?
  3. PreparedStatement связан с Connection, если мое соединение не закрывается после каждого запроса, почему бы не сохранить PreparedStatement и повторно использовать его в других методах?
  4. если мы создаем PreparedStatement для каждого запроса, знает ли база данных, что это тот же PreparedStaement, и игнорирует ненужные действия после первого раза?
  5. PreparedStatement не создать один раз и многократно использовать заявление? если да, то зачем каждый раз закрывать?

Я знаю, что вызов close () освободит ресурс. Но если мы знаем, что собираемся использовать его позже, зачем освобождать его, а затем запрашивать его позже?

Как насчет мультиклиентского приложения? нам нужен пул соединений, поэтому нам нужно каждый раз создавать и закрывать Connection, Statement и PreparedStatement?

спасибо,

Ответы [ 2 ]

14 голосов
/ 24 июня 2009

Лично я бы использовал пул, так как он позаботится обо всем управлении ресурсами для вас. Если ваши требования к соединению изменятся, вы можете легко изменить конфигурацию пула. Имея пул, вы можете открывать / закрывать соединения и подготовленные операторы в соответствии с best-Practice и оставлять управление ресурсами для пула.

Как правило, при использовании пула:

  • закрытие соединения на самом деле просто вернет его в пул
  • акт подготовки оператора либо извлекает ранее подготовленный оператор из кэша операторов Connection, либо, если он недоступен, создает новый оператор и кэширует его для дальнейшего использования.
  • акт закрытия PreparedStatement фактически просто возвращает его в кэш операторов соединения.

Более того - в зависимости от реализации пула - он может уведомить вас о наличии утечек ресурсов, упрощая выявление подобных проблем в вашем коде.

Взгляните на исходный пример реализации, такой как DBCP - интересно посмотреть, как они работают.

3 голосов
/ 01 декабря 2016

1. Даже если у вас один клиент, пул соединений может быть полезен. Подключение к базе данных может занять значительное время, поэтому очень часто это может замедлять работу приложения из-за медленных сетевых запросов. Более того, как объясняет @teabot, пул может помочь определить, не закрывается ли какое-либо соединение.

2. Не стоит открывать соединение и оставлять его открытым навсегда по двум причинам. Сначала соединение может прерваться, если произойдет временное прерывание сети. Чем дольше он открыт, тем более вероятно, что он мертв, когда это необходимо. Во-вторых, неудачная транзакция может оставить соединение в состоянии, не подходящем для продолжения работы. Обычно лучше всего открыть несколько соединений, повторно использовать их в течение пяти или десяти минут, а затем утилизировать.

3. В зависимости от базы данных и драйвера, соединение может иметь подготовленный кэш операторов. Даже если используется другое соединение, СУБД обычно кэширует точно такие же операторы, включая ее параметры. Поэтому SELECT * FROM table WHERE value =? как подготовленный оператор будет кэшироваться через соединения, но если вы укажете значение параметра, например SELECT * FROM table WHERE value = 'your_data', то, вероятно, оно не будет кэшировано на стороне сервера.

4. Как объяснено в 3, зависит от реализации СУБД, сделайте эталонный тест.

5. Нет необходимости закрывать и снова подготавливать оператор, который будет повторно использоваться с другими параметрами. Просто снова установите параметры и выполните.

Для нескольких клиентов база данных всегда будет иметь ограничение одновременных соединений, которое обычно не является большим числом. Если все клиенты проходят через веб-приложение, то с пулом вроде DBCP все в порядке. Но очевидно, что нежелательно создавать пул для каждого клиента с постоянно открытыми несколькими подключениями.

...