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]

Reply via email to