Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

  • Для достижения оптимальной производительности необходимо соблюдать осторожность. не «захватывать» соединение, пока вы на самом деле не используете его для выполнения запроса.Если вы один раз берете соединение из пула, а затем передаете его различным методам, вам нужно убедиться, что вы это делаете не случайно.
  • Не забудьте вернуть свои соединения в пул!(попробуй/наконец-то твой друг здесь...)
  • Во многих системах вы не могу держать соединения открытыми «вечно»:ОС закроет их через некоторое максимальное время.Итак, в методе «возврата соединения в пул» вам нужно будет подумать о «выход на пенсию» связей, которые существуют уже давно (встроить какой-нибудь механизм запоминания, напримеримея объект-оболочка вокруг реального объекта JDBC Connection, который вы можете использовать для хранения таких показателей)
  • Возможно, вы захотите рассмотреть возможность использования подготовленных операторов.
  • Со временем вам, вероятно, придется настроить размер пула соединений

Другие советы

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

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

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

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

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

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

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

:)

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

Пролистать

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

Другой подход к пулам соединений заключается в

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top