Комментарии 38
Понятно что решение обобщённое и подходит для любых ресурсов, а не только соединений с БД, но неужели нельзя в строке подключения указать что-то вроде «Pooling=yes»?
Обожаю статьи типа «Две недели назад я начал заниматься… и вот я решил написать статью...»
Мне всегда нравилась JAVA. Пачка фаилов, для того чтобы только подключится к БД
Наверное правильнее сказать что всего 2 файла и получаем пул соединений. :)
Вы не правы. Захардкодить подключение можно одной строчкой, а пачкой файлов можно добиться гибкости.
Connection conn = DriverManager.getConnection(«jdbc:oracle:thin:127.0.0.1:1521», «system», «sys»);
Реквестирую пачку файлов. Кроме JDBC-драйвера естественно.
Реквестирую пачку файлов. Кроме JDBC-драйвера естественно.
Замечу, что у вас возникнет проблема, если maxWait будет больше чем connection_timeout базы данных. Лучше посмотреть эту ссылку commons.apache.org/dbcp/configuration.html и дописать конфиг
Хотя нет, не так. Не от maxWait это зависит. У нас была проблема с тем, что соединения отвалившиеся по таймауту оставались в пуле
У нас на проекте тоже были проблемы… Мы их «решали» давольно легким способом — перед выполнением запроса делали фейковый запрос к БД. Если он срабатывал, то все хорошо, иначе пересоздавали, хотя система считала, что все нормально… ведь у нее же было открытое потключение :)
Две недели назад я начал писать на Java и теперь, дорогие хабралюди, я расскажу вам о чудном способе вывода «Hello, world»… [*сарказм*]
Так это про кого.
Сдаётся мне, что главная причина, по которой используется пул соединений — это возможность одновременной работы нескольких потоков (threads) приложения. В противном случае потоку, который открывает транзакцию, пришлось бы ещё и тормозить остальные потоки. Кстати, странно, что используется работа с БД напрямую. Есть же JPA, есть же Hibernate. Насколько я знаю, для них пул можно настроить специфическим механизмом.
В посте правильно написано, главная причина — исключить затраты на открытие/закрытие соединения.
Ну не совсем правильно выразился. В посте написано, что можно было бы использовать singleton, но лучше его не использовать, т.к. это пагубно скажется на производительности. А как раз поднимать только одно соединение на всё приложение чревато не столько снижением производительности, сколько невозможности одновременной обработки нескольких запросов.
Не поверите, «для них пул можно настроить специфическим механизмом» внутри hibernate пула лежит примерный такой же механизм описанный автором.
Я бы добавил к статье следующее замечание.
Перед возвратом соединения в пул все Statement'ы и ResultSet'ы, полученные с помощью этого соединения, автоматически закрываются в соответствии с API.
Перед возвратом соединения в пул все Statement'ы и ResultSet'ы, полученные с помощью этого соединения, автоматически закрываются в соответствии с API.
Ну да, так оно и есть. Главное не забывать, что соединение необходимо вовремя закрывать, иначе можем запросто переполнить пул соединений и очередь. Statement и ResultSet тоже лучше закрывать, если они больше не нужны. У меня эта привычка осталась с «древних» времен Turbo C/Pascal когда самому приходилось следить за ресурсами. С моей точки зрения привычка «убирать за собой» при работе приложения на сервере приложений, это хорошая привычка. Каждый объект, будь то EJB, Servlet и пр. имеет свой жизненный цикл и тут уже нельзя полагаться на то, что конкретный экземпляр умрет сразу после обращения и GC унесет весь мусор связанный с ним.
А еще удобнее этим через Spring пользоваться — он сам «вставит» Connection Pool в ваши классы
Похоже вся соль этой статьи выплывает в комментариях)
В конце, как обычно, следует закрыть соединение (conn.close()), однако в отличии от обычного соединения через драйвер JDBC, это соединение на самом деле не закроется: оно будет помечено в пуле как свободное, и его можно будет переиспользовать позже.
Каким образом об этом узнает пул? Как осуществляется обратная связь?
Этот же пул соединений используется в tomcat, в таком случае записывается в контекст приложения.
Основываясь на практическом опыте, могу сказать, что стоит весьма трепетно отнестись к производительности самого пула.
dbcp отличается низкой производительностью. В случае большого количества параллельных обращений к пулу он становится существенным затыком во всей системе. Проблема заключается в неэффективной реализации контейнера объектов (собственно говоря commons-pool), которая использует java synchronized.
Есть несколько альтернатив dbcp: c3p0, proxol, nanopool, miniconanectionpool, Oracle jdbc connection pool и др. После сравнительных тестов производительности мы выбрали Tomcat JDBC Connection Pool. Он использует java concurrent collections, прост в использовании и расширении, а конфигурация совместима c dbcp. Пропускная способность нашего приложения после этой замены варосла приблизительно на 30%.
dbcp отличается низкой производительностью. В случае большого количества параллельных обращений к пулу он становится существенным затыком во всей системе. Проблема заключается в неэффективной реализации контейнера объектов (собственно говоря commons-pool), которая использует java synchronized.
Есть несколько альтернатив dbcp: c3p0, proxol, nanopool, miniconanectionpool, Oracle jdbc connection pool и др. После сравнительных тестов производительности мы выбрали Tomcat JDBC Connection Pool. Он использует java concurrent collections, прост в использовании и расширении, а конфигурация совместима c dbcp. Пропускная способность нашего приложения после этой замены варосла приблизительно на 30%.
Поправил ошибки.
У меня была ошибка: сannot create JDBC driver of class '' for connect URL 'null'
Исправил context.xml так:
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/appname</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
InitialContext initContext= new InitialContext();
DataSource ds = (DataSource) initContext.lookup("java:comp/env/jdbc/appname");
Connection conn = ds.getConnection();
У меня была ошибка: сannot create JDBC driver of class '' for connect URL 'null'
Исправил context.xml так:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/appname" auth="Container"
type="javax.sql.DataSource" maxActive="100"
maxIdle="30" maxWait="10000"
username="username"
password="password"
driverClassName="jdbc.driver.name"
url="jdbc:protocol://hostname:port/dbname"/>
</Context>
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Database Connection Pool