15
December

Использование 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;
  }
}

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

7 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?

Leave a comment

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