DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://issues.apache.org/bugzilla/show_bug.cgi?id=28912>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://issues.apache.org/bugzilla/show_bug.cgi?id=28912 Connection re-use conflates logical and physical connections Summary: Connection re-use conflates logical and physical connections Product: Commons Version: 1.1 Final Platform: All OS/Version: All Status: NEW Severity: Major Priority: Other Component: Dbcp AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] [Let me say up front that you may already know about this, but I couldn't find anything like this in the dev list or the bug DB. I may just be using different terms than you. If so, sorry.] I just debugged a problem with a finalizer closing a connection that had been re-allocated from the pool to a different use, and what this made clear to me is the following: DBCP is pooling physical connections and using them as logical connections. This will cause all sorts of problems like this. First, my terms: A physical connection is a lower-level JDBC Connection object that talks to a database. A logical connection is a user level concept that flows from using getConnection() and continues until the user code invokes close(). ("User" here means "programmer using DBCP".) Physical connections are expensive to establish and so need pooling. But logical connections can be cheap. What I would recommend is that you put an object representing the logical connection between the user and the physical connection. The physical connections would be pooled, but the logical ones would be created during getConnection() to represent the user's notion of a single connection. The logical connection would maintain state for the logical connection, such as isClosed(). Here is an example of code that, while stupid, should work -- it does work in the absence of a pooled connection: Connection conn = getConnection(); conn.executeQuery(query); conn.close(); Thread.sleep(30 * 1000); conn.close(); While dumb, this is exactly what happened to me, except that the delay between close() calls was the delay between the explicit close and when the garbage collector invoked a finalize() method. The problem here is that someone else may have picked up the physical connection after the first clase, and be using it when the second close occurrs. The reason this problem exists is that you are handing me phyiscal connections. If instead you put a logical connection object in the middle, the logical connection object would know that it was closed and the second close would act appropriately (throwing an exception, I think, is correct). This is because the second use of the physical connection would be using a different object implementing Connection with its own state, and so my old Connection object would not be accessing the physical connection any more. In other words, as a user, I should never get my hands on physical connection objects. This reduces the number of ways I can screw up myself or, in this case, others. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
