barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

четверг, 2 февраля 2012 г.

Быстрый старт: использование пула соединений с БД в веб-приложении, разворачиваемом на Tomcat 6

Одной из возможностей, предоставляемых контейнером сервлетов является использование пула соединений с БД, позволяющего более эффективно взаимодействовать с ней благодаря возможности повторного использования уже открытых соединений вместо создания новых.
Неплохое HOWTO по этой теме есть в документации Tomcat, ниже я приведу короткую выдержку оттуда для случая создания пула соединений к Postgres и его использования в сервлете.
1) Описываем JNDI-ресурс в context.xml веб-приложения (META-INF/context.xml, подробнее про элемент Context можно почитать тут), разместив внутри тега <Context> следующее:
<Resource name="jdbc/myDb"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="postgres"
password="postgres"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/myDB"/>

Здесь "jdbc/myDb" - это имя ресурса, по которому он будет доступен из приложения.
2) Описываем ссылку на ресурс в web.xml приложения:
<resource-ref>
<description>It`s myDb DataBase</description>
<res-ref-name>jdbc/myDb</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

3) Теперь в коде сервлета мы можем получить соединение следующим образом:

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.sql.Connection;
// ...
Context initContext = new InitialContext();
Context envContext  = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/myDb");
Connection jdbcConn = ds.getConnection();
4) Завершив работу с соединением, его можно закрыть, как обычно:
jdbcConn.close();
jdbcConn = null;
При этом запись null`а позволит Вам случайно не закрыть это соединение повторно где-нибудь в блоке finally, что очень опасно при использовании пула соединений: если первый вызов close() всего лишь сигнализирует томкату, что приложение больше не нуждается в соединении и он может отдать его другому потоку, то повторный вызов действительно закроет соединение, которое на момент этого вызова может быть уже отдано другому потоку!

Комментариев нет:

Отправить комментарий