tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Josh Gooding <josh.good...@gmail.com>
Subject Re: ConnectionPool question
Date Tue, 03 Nov 2009 19:01:38 GMT
Elle,

I am going to dig into this code and check it out.  I want to know more
about how to use threadlocal and filters.  (Sorry I'm not as experienced in
Tomcat as some for you gurus here).

The code looks promising and I like the 2nd option due to the fact that each
HTTP req. only has one connection (which should drop the overhead immensely)
however for right now, I just want to fix the bleeding issue (which it seems
that I have caught a good portion of them), so I'll use my legacy code, but
during a "minor" code release, I can definitely look into rolling this out.
I am getting a ton of "abandoned" conenction warnings in the console window,
so I need to find out where these are coming from now.

I don't know where to begin thanking you guys but thank you.  I've gotten
more mentoring here on this listing than I have in 2 years at my current
employer.  Thank you all again.

- Josh

On Mon, Nov 2, 2009 at 3:40 PM, Christopher Schultz <
chris@christopherschultz.net> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Elli,
>
> 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
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.10 (MingW32)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>
> iEYEARECAAYFAkrvQ8AACgkQ9CaO5/Lv0PDOSACeJfqgaXmrySSKItQHji2K6UzK
> hmsAoKIAhRAgwzI/QN8SPdVGkBbewA2a
> =Mqjn
> -----END PGP SIGNATURE-----
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message