On Thu, 31 Jan 2003, shawn wrote:
> Date: 31 Jan 2003 10:35:30 +0900 > From: shawn <[EMAIL PROTECTED]> > Reply-To: Tomcat Users List <[EMAIL PROTECTED]> > To: Tomcat Users List <[EMAIL PROTECTED]> > Subject: DBCP leak ? > > As noted in Tomcat docs, > > A web application has to explicetely close ResultSet's, Statement's, and > Connection's. > > I am using a web app that opens a ResultSet locally (in a method) but it > never gets closed (gc'd sometime I presume). > In the immortal words of Walt Kelly's POGO comic strip (if you're old enough to remember): "we have met the enemy and they is us". :-) > Under Oracle, a user is hitting the maximum number of Oracle process and > I presume it is a leak. > Yes ... but it's in your application, not the driver. > Three questions. > > 1) must a local ResultSet be explicitely closed to avoid a leak Some JDBC drivers will close the ResultSet for you if you close the associated Statement, but it sounds like you're probably not doing that either. Waiting for the GC to roll around and clean up after you (even if that actually works; I wouldn't be surprised to find JDBC driver bugs in that area) is still a very bad design choice -- because the resources allocated to the unclosed objects are tied up for seconds to minutes (until the GC gets to them) instead of milliseconds (if you explicitly close everything as soon as you are done with it). Therefore, an application configured with X database connections in its pool can serve X simultaneous users (if you close all the time), but substantially less than X (sometimes even zero) users if you wait for the GC to clean up. > > 2) if I use, <parameter> > <name>logAbandoned</name> > <value>true</value> > </parameter> > > to log the stack trace, where is that log? Under logs in the usual place for that >context. > I have to tell someone else where to find the log otherwise would just look for it >myself (ie I'm not running Oracle). > DBCP uses System.out for these logs, which goes to $CATALINA_HOME/logs/catalina.out unless you've used the "swallowOutput" attribute on your <Context> element -- in which case, it goes wherever the <Logger> for your <Context> element puts it. > 3) If only Oracle shows this behavior what could account for that? > Diff jvm? (just curious) > Different JDBC drivers and different JVMs definitely behave differently -- but your fundamental design pretty much guarantees that you are going to have worse performance than you should, on any database driver or any JVM. You should learn to apply a fundamental design pattern for database access when using a connection pool: DataSource ds = ... acquire a DataSource object ...; Connection conn = null; Statement stmt = null; ResultSet rs = null; try { conn = ds.getConnection(); stmt = conn.createStatement(); rs = stmt.executeQuery("SELECT ..."); ... use the result set, or pass it to other classes to use ... } catch (SQLException e) { ... deal with exception ... } finally { if (rs != null) { try { rs.close(); } catch (SQLException e) { ; } rs = null; } if (stmt != null) { try { stmt.close(); } catch (SQLException e) { ; } stmt = null; } if (conn != null) { try { conn.close(); // Returns connection to the connection pool } catch (SQLException e) { ; } conn = null; } } This approach *guarantees* that you will always clean up, no matter when an SQLException might happen, and means that the code you pass the result set to doesn't have to worry about cleaning up -- the "finally" block will take care of that. > TIA > > -- > shawn Craig --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]