Сколько соединений JDBC в Java?
-
19-08-2019 - |
Вопрос
У меня есть программа на 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 и т. д. между потоками - безусловно, лучшая политика - использовать их в том же потоке, который их создал; это обычно легко, потому что эти объекты обычно не хранятся слишком долго.