Фундаментальная проблема в пуле соединений Tomcat - PullRequest
10 голосов
/ 03 апреля 2012

Я использую пул соединений Tomcat 7 (в качестве ресурса Tomcat в server.xml и context.xml) в веб-приложении, и он работает.
Мой вопрос: можно ли "сказать" / "заставить"Tomcat, чтобы утилизировать пул соединений после его создания?

Причина, по которой я спрашиваю, заключается в следующем:
Я использую H2 и сталкиваюсь с какой-то "гоночной" проблемой при завершении работы.
H2 остается открытым, пока открыто соединениено Tomcat не располагает пулом соединений, поэтому соединения остаются открытыми.И в результате у меня возникают различные проблемы с отключением.

Я обнаружил, что могу выполнить команду SQL SHUTDOWN, чтобы закрыть H2, но я хочу изучить все альтернативы для моего случая.

Так можно ли "сказать" / "заставить" tomcat утилизировать пул соединений (по крайней мере, при выключении)?

Ответы [ 5 ]

1 голос
/ 30 ноября 2012

Как насчет написания пользовательского ServletContextListener и последующего его закрытия при удалении контекста? Вот статья о ServletContextListener, используемом для создания ловушек отключения:

крюк отключения для веб-приложения Java

API для слушателей контекста кажется довольно простым:

http://docs.oracle.com/javaee/5/api/javax/servlet/ServletContextListener.html

1 голос
/ 09 апреля 2012

Я думаю, вы можете попытаться включить журнал отладки и проверить, не связана ли его проблема с соединением, не выпущенным приложением, или с чем-то другим, например с параметром конфигурации источника данных в server.xml.

В основном это должно быть в том случае, когда приложениене освобождает соединение.

0 голосов
/ 10 марта 2013

Может быть, я не понимаю вопроса. Чтобы быть более понятным, если вы выключите Tomcat (и, следовательно, это JVM), то ни Tomcat, ни его пулы соединений, ни какой-либо из потоков его демонов не будут работать ... и, следовательно, ссылки на память не останутся в буфере.

Как именно вы пришли к выводу, что ресурс Tomcat имеет ссылку на пул соединений после завершения работы Tomcat? Вы не сможете увидеть это в профилировщике, и, честно говоря, это не совсем имеет смысла. Например, возможно ли, что ОС будет держать соединения открытыми в течение короткого периода времени, прежде чем уничтожать их? Вы пробовали те же тесты, используя ту же ОС, но вместо этого с другим контейнером, чем-то вроде Jetty? Используете ли вы keep-alive или какие-то постоянные соединения?

Если вы хотите не справляться с управлением Tomcat ресурсом, предоставляемым через JNDI, вы можете создать собственную реализацию DataSource, которая делегирует H2SSource. Вы можете сделать это, используя атрибут factory-method в вашем server.xml (или context.xml)

Вот рабочий пример на github: https://github.com/tvollmer/connection-factory

Кроме того, было бы полезно, если бы вы могли уточнить, что вы подразумеваете под «различными проблемами при выключении». Эти детали имеют значение, и мне не ясно, как вы логически перешли от «различных проблем» к утверждению, что Tomcat «не располагает пулом соединений». Здесь вы можете столкнуться с двумя совершенно разными проблемами и, возможно, захотите проверить параметры antiResourceLocking и antiJARLocking для Tomcat в Windows.

0 голосов
/ 12 октября 2012

Как описано в документации http://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Resource_Definitions возможно установить closeMethod источника данных контейнера.Я не уверен насчет «удаления» пула соединений, но думаю, что стоит попробовать.

Имя метода с нулевым аргументом для вызова одноэлементного ресурса, когда он больше не требуется.Это предназначено для ускорения очистки ресурсов, которые в противном случае произошли бы как часть сборки мусора.Этот атрибут игнорируется, если атрибут singleton имеет значение false.Если не указано иное, значение по умолчанию не определено и метод вызова не будет вызываться.

Также вы можете программно развернуть DataSource и запустить / остановить его в ServletContextListener, например, для dbcp (извините, этоиз моих юнит-тестов, но легко переписать):

import org.apache.commons.dbcp.BasicDataSource;

static BasicDataSource bds = new BasicDataSource();

@BeforeClass
public void setUp() throws Exception {
    bds.setDefaultAutoCommit(false);
    bds.setDriverClassName("org.h2.Driver");
    bds.setInitialSize(0);
    bds.setMaxActive(2);
    bds.setMaxWait(10000);
    bds.setPassword(null);
    bds.setUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
    bds.setUsername("sa");
    bds.setValidationQuery("select 1 as test");
}

@AfterClass
public void tearDown() throws Exception {
    bds.close();
}
0 голосов
/ 23 августа 2012

см. Мой ответ в: Проблема специфичных для контекста параметров JNDI в tomcat 6 .С ресурсом jndi можно многое сделать.

<Resource name="jdbc/NAME" auth="Container" type="javax.sql.DataSource"
               maxActive="100" minIdle="10" maxWait="10000" removeAbandoned="true"
               removeAbandonedTimeout="60" logAbandoned="true"
               testWhileIdle="true" testOnBorrow="true" testOnReturn="false"
               timeBetweenEvictionRunsMillis="5000"
               validationQuery="SELECT 1" initialSize="10"
               username="usrname" password="password"   
               driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/databb?autoReconnect=true"/>
...