Hi, > Elli, > > On 11/4/2009 7:01 PM, Elli Albek wrote: >> I also >> remember that closing a connection closes statements and result sets, but it >> has been a while since I read the source. > > Pooled connections are almost certainly not behaving this way. This has > been discussed at least twice in the last week or two, and, I believe, > already once in this thread. > > - -chris
This is certainly not the case for my DBCP library (1.2.2). I just stepped through the source code: Calling connection.close() is closing result sets and statements. In addition I commented the code that closes statements and result sets in our framework to create a leak, and DBCP closed everything. Relevant DBCP Code snippets below. Josh: You are correct, wrapping connections, statements and datasources is not a good idea. It is complicated code and can lead to many problems. Fortunately for you, you don’t have to do that. You can recklessly leave statements and result sets open, and as long as you call connectiohn.close() at the end DBCP will do all the work for you. You can verify this by downloading the source code, and putting a break point just before you call close. I am telling you this based on experience. We do wrap everything for logging purpose (data source, connection, statement). Doing it was far from trivial, even using the DBCP ready-to-use wrapper classes (DelegatingConnection, DelagatingStatement…). Of course is it good to follow best practices and close things as soon as possible in finally blocks. But in your case, it may just be an unnecessary intermediary step that you can skip. Maybe you can start with a brute force filter and rely on the good fellows that wrote DBCP to clean up the mess. Then go to a better solution, where you use a framework that does most of this work for you. There are too many java database frameworks to list, some of them are heavy, some are minimal right above the JDBC layer, and still provide automatic closing of resources. Below is the DBCP code that keeps track of open statements/result sets and closes them when the connection is closed (BDCP 1.2.2). PollableConnectionFactory: public void passivateObject(Object obj) throws Exception { ... if(obj instanceof DelegatingConnection) { ((DelegatingConnection)obj).passivate(); } } DelegatingConnection (called via subclass PollableConnection): protected void passivate() throws SQLException { try { // The JDBC spec requires that a Connection close any open // Statement's when it is closed. List statements = getTrace(); if( statements != null) { Statement[] set = new Statement[statements.size()]; statements.toArray(set); for (int i = 0; i < set.length; i++) { set[i].close(); } clearTrace(); } setLastUsed(0); if(_conn instanceof DelegatingConnection) { ((DelegatingConnection)_conn).passivate(); } } finally { _closed = true; } } Delegating statement: public void close() throws SQLException { try { try { if (_conn != null) { _conn.removeTrace(this); _conn = null; } // The JDBC spec requires that a statment close any open // ResultSet's when it is closed. // FIXME The PreparedStatement we're wrapping should handle this for us. // See bug 17301 for what could happen when ResultSets are closed twice. List resultSets = getTrace(); if( resultSets != null) { ResultSet[] set = (ResultSet[]) resultSets.toArray(new ResultSet[resultSets.size()]); for (int i = 0; i < set.length; i++) { set[i].close(); } clearTrace(); } _stmt.close(); } catch (SQLException e) { handleException(e); } } finally { _closed = true; } } --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org