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 < ch...@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-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > >