tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christopher Schultz <>
Subject Re: ConnectionPool question
Date Mon, 02 Nov 2009 20:40:32 GMT
Hash: SHA1


On 11/2/2009 4:08 AM, Elli Albek wrote:
> I think you can have a solution without changing your code.
> Try something like this:
> getConnection() static method should get the connection, and add it to a
> list that you keep in threadlocal.
> recycleConnection() should close the connection and remove the connection
> object from thread local.
> Add a servlet filter that closes all connections in thread local. The filter
> calls next filter, and in a finally block get the connections from thread
> local, close all of them, and clear the list in thread local.

This is a horrible, nasty hack and it's entirely brilliant!

I would change Elli's implementation just slightly, and actually write
your own DataSource implementation that piggybacks on another one.
Basically, you just wrap the DataSource that Tomcat provides either by:

a. Using JNDI to look-up the Tomcat-created JNDI DataSource and just
   writing the plumbing code to pass everything through
b. Actually subclass the DataSource class(es) provided by Tomcat and
   use /those/ in your <Resource> configuration.

I would also not make any of this static... there's just no reason to do
so, especially if your DataSource object is in the JNDI context.

Although the /real/ solution is to fix the code, I really like this
solution for a couple of reasons:

1. It requires no wrapping of Connection, Statement, etc. objects
   (which is entirely miserable if you've ever had to do it)
2. It requires no changes to your code whatsoever (if you use my
   DataSource-wrapping suggestion above)
3. You won't end up closing your connection, statement, result set, etc.
   too early because your code has completed execution (unless you
   are using JDBC resources across requests, which is another story)

What this won't help, unfortunately is:

* Closing your ResultSet and Statement objects (though this can be
  solved by wrapping the Connection, Statement, etc. objects handed-
  out by your DataSource. Yes, it's miserable.)

> This will allow you to keep your legacy code. As far as I remember DBCP has
> an option to close the result sets and statements when you close the
> connection. If not this will partly work.

I don't believe commons-dbcp has this capability at all. I'm willing to
read any documentation to the contrary, though.

> Version 2: Advanced
> Keep the actual connection in thread local. You will have one connection per
> HTTP request. getConnection() should be something like
> public static /* NOT synchronized */ Connection getConnection(){
> Connection c = ...// get the connection from thread local
> if (c != null)
> return c;
> Connection c = ...// get the connection from JNDI/DBCP
> // put connection in thread local
> return c;
> }

I like this technique, too. You just have to decide if it's acceptable
for your webapp to re-use connections. I can't imagine why that would be
a problem, but it's worth considering before you blindly do it. This
optimization can save you from deadlock (though you're killing-off
connections after 15 seconds anyway) and should significantly improve
the performance of your webapp because you won't be bleeding so many
connections: you're limited to bleeding one connection per request
instead of potentially dozens.

> recycleConnection(){
> // empty, connection will be recycled by filter.
> }

I would actually allow recycleConnection to close the connection, and
have the filter call recycleConnection. That way, as you improve your
webapp's code, the connections will be closed as soon as possible
instead of waiting until the request is (mostly) finished.

Again, Elli, a great suggestion!

- -chris
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla -


To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message