简体   繁体   中英

Fundamental issue in connection pooling of Tomcat

I am using Tomcat 7 connection pooling (as a Tomcat resource in server.xml and context.xml) in a web application and it works.
My question is: Is it possible to "tell"/"force" tomcat to dispose the connection pool after it is created?

The reason I ask is the following:
I am using H2 and run into some "racing" issue on shutdown.
H2 remains open as long as there is a connection open but Tomcat does not dispose the connection pool and so connections remain open. And as a result I have various issues on shutdown.

I found that I could issue an SQL SHUTDOWN command to close H2 but I want to explore all the alternatives for my case.

So is it possible to "tell"/"force" tomcat to dispose the connection pool (at least on shutdown)?

I think you can try to put debug log on and check whether its issue with connection not released by application or something else like datasource configuration parameter in server.xml.

mostly it should be the case where application is not releasing connection.

How about writing a custom ServletContextListener and then having it shut down the pool when the context is destroyed. Here's an article about ServletContextListener being used to create shutdown hooks:

shutdown hook for java web application

The API for context listeners seems pretty straightforward:

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

please see my answer in : Context specific JNDI parameters problem in tomcat 6 . There's a lot of stuff you can do with jndi resource.

<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"/>

As described in documentation http://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Resource_Definitions it possible to set closeMethod of container datasource. I'm not sure about 'disposing' connection pool, but i think it worth a try.

Name of the zero-argument method to call on a singleton resource when it is no longer required. This is intended to speed up clean-up of resources that would otherwise happen as part of garbage collection. This attribute is ignored if the singleton attribute is false. If not specificed, no default is defined and no close method will be called.

Also you can deploy DataSource programmatically and start/stop it in ServletContextListener , example for dbcp (sorry, it from my unit-tests, but easy to rewrite):

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();
}

Maybe I don't understand the question. To be more clear, if you shutdown Tomcat (and hence it's JVM), then neither Tomcat nor it's connection pools, nor any of it's daemon threads would still be alive ... and thus no memory references would be left in tack.

How exactly have you come to the conclusion that a Tomcat resource has a reference to a connection pool, after Tomcat is shutdown? You wouldn't be able to see that in a profiler, and frankly, it doesn't quite make sense. For example, is it possible that the OS keeps connections open for a short period of time before destroying them? Have you tried the same tests using the same OS, but instead with a different container, something like Jetty? Are you using keep-alives, or some form of persistent connections?

If you want to get down-and-dirty with Tomcat's management of a resource exposed through JNDI, you can make your own DataSource implementation that delegates to the H2 DataSource. You can do this my using the factory-method attribute within your server.xml (or context.xml)

Here's a working example on github : https://github.com/tvollmer/connection-factory

Beyond that, it would help if you could further clarify what you mean by "various issues on shutdown". Those details matter, and it's not clear to me how you've logically gone from "various issues" to saying that Tomcat "does not dispose the connection pool". You could be dealing with 2 completely separate issues here, and you may want to check out antiResourceLocking and antiJARLocking settings for Tomcat on Windows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM