15
December
2005

Использование Connection Pool (DBCP) в Tomcat

Posted in: Java open-source проекты, Java technologies, J2SE |

В на�?е время трудно представить себе веб-приложение, которое не использовало бы базу данных для своих нужд. При работе с базой данных очень важно следить за соединениями к базе и вовремя освобождать их. Для этих целей разработчики веб-приложений пи�?ут так называемые Connection Pools (или же используют/исправляют существующие).
Одним из луч�?их сервлет-контейнеров есть Apache Tomcat. Tomcat хоро�?о еще и тем, что он использует свой собственный DBCP (Database Connection Pool).
О том, как в полной мере воспользоваться преимуществами DBCP сервера Tomcat, и будет эта статья.

Предположим, в сети по IP-адресу 192.168.0.5 находится Oracle с базой данных TESTDB и пользователем DBuser с паролем DBpass.
Для того, чтобы настроить Tomcat на эту базу, необходимо в конфигурационном фале conf\server.xml в раздел Context (если нету, необходимо создать его внутри раздела Host непосредственно перед его окончанием) добавить следующие строки:

<resource name=“newDS” auth=“Container”
type=“javax.sql.DataSource”/>
<resourceparams name=“newDS”>
  <parameter>
    <name>factory</name>
    <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
  </parameter>
  <parameter>
    <name>url</name>
    <value>jdbc:oracle:thin:@192.168.0.10:1521:TESTDB</value>
  </parameter>
  <parameter>
    <name>username</name>
    <value>DBuser</value>
  </parameter>
  <parameter>
   <name>password</name>
    <value>DBpass</value>
  </parameter>
  <parameter>
     <name>driverClassName</name>
     <value>oracle.jdbc.driver.OracleDriver</value>
  </parameter>
  <parameter>
    <name>maxActive</name>
    <value>100</value>
  </parameter>
  <parameter>
    <name>maxIdle</name>
    <value>10</value>
  </parameter>
  <parameter>
    <name>maxWait</name>
    <value>10000</value>
  </parameter>
  <parameter>
    <name>removeAbandoned</name>
    <value>true</value>
  </parameter>
  <parameter>
    <name>removeAbandonedTimeout</name>
    <value>60</value>
  </parameter>
</resourceparams>

С помощью этой конфигурации создается Data Source с именем newDB. Рассмотрим параметры этого объекта.
Параметр factory говорит о том, какую фабрику нужно использовать для создания объектов, реализующих интерфейс DataSource. Следующий параметр представляет собой URL для доступа к базе данных. Параметры username и password содержат соответсвенно имя пользователя/схемы и пароль. �?мя драйвера базы данных указано в параметре driverClassName.
Следующие параметры отвечают непосредственно за Connection Pool. Рассмотрим их немного подробнее.
maxActive - максимальное количество соединений, которые будут содержаться в пуле. Если значение этого параметра установить в 0, то ограничения на кол-во подключений к базе не будет. В конфигурации самого сервера баз даннных такой параметр тоже существует. Думаю не стоит объяснять, почему его значение должно быть боль�?е, чем maxActive.
maxIdle - максимальное количество простаивающих соединений, которые будут оставаться в пуле. При значении этого параметра равным нулю, ограничений не будет.
maxWait - если время ожидания соединения превысит значение параметра maxWait (в миллисекундах), пользователь получит Exception. При значении maxWait равным -1, время ожидания не ограничено. Про�?у обрать ва�?е внимание на следующую очень важную вещь. Tomcat работает под виртуальной ма�?иной (JVM). Для освобождения памяти JVM использует сборщик мусора (garbage collector). GC имеет очень высокий приоритет и при освобождении памяти Tomcat будет входить в состояние ожидания (на доли секунды, реже - на несколько секунд). При маленьких значениях maxWait, соединение может не установиться из-за таймаута. Значение 10000 в подавляющем боль�?инстве случаев будет оптимальным.
removeAbandoned - при установке этого парамера в true, забро�?енные соединения будут освобождены, когда кол-во свободных соединений в пуле невелико.
removeAbandonedTimeout - этот параметр указывает в секундах время, через которое любое простаивающее соединение будет считаться забро�?енным.
После этого, нужно настроить на�?е веб-приложение для работы с DataSource. Делается это так, в файле-дескрипторе web.xml пи�?ем:

<resource -ref>
  <description>Описание ресурса</description>
  <res -ref-name>newDB</res>
  <res -type>javax.sql.DataSource</res>
  <res -auth>Container</res>
</resource>

Наконец-то мы и добрались до использования всего вы�?енаписанного на практике. Чтобы доступиться до на�?его DataSource через JNDI и создавать соединения с базой можно написать такой себе класс (импорт пакетов и обработка о�?ибок опущены):

public class ConnectionFactory {
  private static final String DATASOURCE_NAME = “newDB”;
  private static DataSource ds = null;

  static {
    Context initContext = new InitialContext();
    Context envContext = (Context)initContext.lookup(“java:/comp/env”);
    ds = (DataSource) envContext.lookup(DATASOURCE_NAME);
  }

  public static Connection getConnection() throws SQLException{
    Connection conn = ds.getConnection();
    return conn;
  }
}

Жду ва�?их комментариев.

13 Comments »

RSS feed for comments on this post. TrackBack URI



хискер
December 19, 2005 #

я не согласен с данной статьей. в коде есть существенные о?ибки! автор статьи должен знать, что “?спользование Connection Pool в Tomcat” не рекомендуемо самим же SUN’ом.

December 19, 2005 #

tо хискер: очень хоро?о, что кто-то не согласен. Это поможет быстрее прийти к правильному ре?ению. Сразу хочу обратить Ва?е внимание:
1. Статья написана, чтобы показать как использовать Connection Pool сервера Tomcat. Все написаное в статье испробовано лично и в статье отражено мое личное понимание всего происходящего.
2. Как указано в статье, в примере кода импорт пакетов и обработка Exception опущены.
Буду очень признателен, если критика будет подтверждена конкретными фактами: ссылками на статьи Sun’a и указанием на о?ибки в коде.

Андрей
March 29, 2006 #

Статья замечательная, просто и понятно, но так же как и во всех статья про DBCP не раскрыт термин maxIdle. Мне лично до сих пор не понятно, что такое простаивающие и забро?енные соединения и как Tomcat определяет эти типы соединений.

March 30, 2006 #

Забро?енные соединения - это условный термин. Tomcat обозначает соединение как забро?енное по значению параметра removeAbandonedTimeout. Это сделано из тех соображений, что в некоторых ситуациях idle соединения могут возникнут в результате некорректной работы программы (сбоев). Поэтому нужно иметь хоть какую-то возможность отследить это и освободить такого рода connections.

Dimitri
May 26, 2006 #

странно, у меня работает и без какого-то изменения web.xml.
Скажите, что я делаю не так ?

Mihaltos
March 15, 2007 #

Расскажите поконкретней - как прописывется таг . Я его прописываю и Tomcat не хочет грузиться!

Меня интересует тег Context - я его прописываю в Tomcate, а он не хочет запускаться!

Андрей
October 29, 2007 #

Если скажем, мой запрос выполняется около 60 секунд, а параметр removeAbandonedTimeout=30, то соединение для данного запроса после 30 сек. будет считаться заброщенным и возвращено в пул, а сам запрос получит Exception?

Александр
November 26, 2008 #

Я начинающий…
> Context initContext = new InitialContext();
Откуда Context … подскажите библиотеку?

Nitro
April 25, 2009 #

> Откуда Context … подскажите битоблиотеку?
javax.naming.*

Статья отличная.

Кое что добавлю:

Тег позволяет задать режим аутентификации пользователя при попытке установки соединения с БД. Значение «Container» говорит, что аутентификацию будет выполнять контейнер на основе предоставленных ему идентификатора и пароля (или сертификата) пользователя (например, реквизиты пользователя указывались в дескрипторе для пула соединений с выбранной СУБД). Другое возможное значение – «Application» – говорит о том, что параметры пользователя должны явно указываться на уровне Java-кода при обращении к фабрике соединений с СУБД.

Nitro
April 25, 2009 #

>Меня интересует тег Context - я его прописываю в Tomcate, а он не хочет запускаться!

Правильно. Надо писать context.

Nitro
April 25, 2009 #

Сорри. Пи?е?ь правильно. Причина не в этом.

SergerFu
September 17, 2009 #

да.милей?ий,вы пробовали пользоваться Prepared Statement или ORA REF курсор или BLOB ей доставать?… попробуйте…. обсудим… такие милей?ие баги вываливает Cast о?ибки,или Delegate не выдает делегированные обьекты или они не кастуются OracleConnection из обычного Connection.

Vermut
December 23, 2009 #

У меня есть некоторые опасения:
1. Tomcat только создает ресурсы с помощью фабрик, в данном случае пул соеденений. Но помоему он не управляет их жизенным циклом, то есть его не интересует их корректное уничтожение. Необходимо в server.xml прописать слу?ателя жизненного цикла сервера, который закроет пул.

2. Пул прописан в server.xml, а не в контесте приложения, если предполагается рас?арить его на несколько приложений, то следует остерегаться:
2.1 Утечки соеденений в одном приложении, выведут из строя, другие приложения использующие этот пул.
2.2 Наверно будет затруднительно определить в каком именно приложении происходят утечки, или вобще сколько конкретное приложение требует соеденений.

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong> <pre>