Сколько JDBC-соединений в Java? - PullRequest
17 голосов
/ 23 января 2009

У меня есть программа на Java, состоящая из около 15 методов. И эти методы очень часто вызываются во время выполнения программы. В настоящий момент я создаю новое соединение в каждом методе и вызываю операторы для них (база данных настроена на другом компьютере в сети).

Что я хотел бы знать: я должен создать только одно соединение в методе main и передать его в качестве аргумента всем методам, которым требуется объект соединения, поскольку это значительно уменьшит число объектов соединения в программе, вместо создания и закрытия соединений очень часто в каждом методе.

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

Ответы [ 5 ]

22 голосов
/ 23 января 2009

Да, вам следует подумать о повторном использовании соединений, а не о создании новых каждый раз. Обычная процедура:

  • сделайте предположение о том, сколько одновременных соединений может разумно обрабатывать ваша база данных (например, начните с 2 или 3 на процессор на компьютере базы данных, пока не обнаружите, что это слишком мало или слишком много - оно будет зависеть о том, насколько жестко связаны ваши запросы)
  • создайте пул из этого множества соединений: по сути, класс, который вы можете запросить «следующее бесплатное соединение» в начале каждого метода, а затем «передать обратно» в пул в конце каждый метод
  • ваш метод getFreeConnection () должен вернуть бесплатное соединение, если оно доступно, иначе либо (1) создайте новое, до максимального количества соединений, которое вы решили разрешить, либо (2), если максимальное уже созданы, подождите, пока один из них не станет свободным
  • Я бы рекомендовал класс Semaphore для управления соединениями; У меня на сайте есть небольшая статья о управлении пулом ресурсов с помощью семафора с примером, который, я думаю, вы могли бы приспособить к своей цели

Пара практических соображений:

  • Для достижения оптимальной производительности вам нужно быть осторожным , чтобы не "зацепить" соединение, пока вы фактически не используете его для запуска запроса . Если вы берете соединение из пула один раз, а затем передаете его различным методам, вам нужно убедиться, что вы случайно не делаете это.
  • Не забудьте вернуть соединения в пул! (попробуй / наконец, твой друг здесь ...)
  • Во многих системах вы не можете держать соединения открытыми «навсегда» : O / S закроет их через некоторое максимальное время. Таким образом, в вашем методе «вернуть соединение с пулом» вам нужно будет подумать о «удаляющих» соединениях, которые существовали долгое время (создайте некоторый механизм для запоминания, например, имея объект-оболочка вокруг фактического объекта JDBC-соединения, который можно использовать для хранения таких метрик, как этот)
  • Возможно, вы захотите использовать подготовленные заявления.
  • Со временем вам, вероятно, потребуется настроить размер пула соединений
9 голосов
/ 23 января 2009

Вы можете передать соединение или, что еще лучше, использовать что-то вроде Jakarta Database Connection Pooling. http://commons.apache.org/dbcp/

8 голосов
/ 23 января 2009

Для этого следует использовать пул соединений.

Таким образом, вы можете запросить соединение и освободить его, когда закончите с ним, и вернуть его в пул

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

Таким образом, вы можете оставить свое приложение каким-то образом, как оно есть (и не передавая соединение вокруг), и все равно правильно использовать ресурсы.

К сожалению, первоклассные ConnectionPools не очень просты в использовании в автономных приложениях (они используются по умолчанию на серверах приложений). Возможно, микроконтейнер (например, Sping) или хорошая структура (например, Hibernate) позволят вам использовать один.

Они не слишком сложны, чтобы их можно было кодировать с нуля.

:)

Этот поиск в Google поможет вам узнать больше о том, как его использовать.

Скользить через

3 голосов
/ 24 января 2009

Многие драйверы JDBC выполняют пул соединений для вас, поэтому в этом случае нет особого преимущества в дополнительном пуле. Я предлагаю вам проверить документацию для вашего драйвера JDBC.

Другой подход к пулам соединений -

  • Иметь одно соединение для всего доступа к базе данных с синхронизированным доступом. Это не допускает параллелизма, но очень просто.
  • Сохранение соединений в переменной ThreadLocal (override initialValue ()). Это хорошо работает, если имеется небольшое фиксированное количество потоков.

В противном случае я бы предложил использовать пул соединений.

1 голос
/ 24 января 2009

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

В зависимости от вашего драйвера может также оказаться возможным разделить соединение между потоками - это тоже будет нормально, если вы доверяете своему драйверу не лгать о его безопасности потоков. Для получения дополнительной информации см. Документацию к вашему драйверу.

Обычно объекты, расположенные ниже «Соединения», нельзя безопасно использовать из нескольких потоков, поэтому обычно не рекомендуется разделять объекты ResultSet, Statement и т. Д. Между потоками - безусловно, лучшая политика - использовать их в том же потоке, который их создал; это обычно легко, потому что эти объекты обычно не хранятся слишком долго.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...