commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jason Lea <ja...@kumachan.net.nz>
Subject Re: DBCP: Closed connections
Date Sun, 27 Apr 2003 02:50:22 GMT
Jason Lea wrote:
> Craig R. McClanahan wrote:
> 
>>
>> On Fri, 25 Apr 2003, Robert Egan wrote:
>>
>>
>>> Date: Fri, 25 Apr 2003 14:00:30 -0400
>>> From: Robert Egan <regan@ph.com>
>>> Reply-To: Jakarta Commons Users List <commons-user@jakarta.apache.org>
>>> To: 'Jakarta Commons Users List' <commons-user@jakarta.apache.org>
>>> Subject: RE: DBCP: Closed connections
>>>
>>> In an effort to muddy the waters more, perhaps some clarification is in
>>> order.
>>>
>>> If a Statement, PreparedStatement, or CallableStatement directly 
>>> produces a
>>> ResultSet (via SELECT) then that result set is closed when the 
>>> associated
>>> statement is closed.
>>>
>>> However, if a result set was produced another way (such as selecting 
>>> into a
>>> REF CURSOR) then that result set is not closed, at least in the Oracle
>>> driver(s).
>>
>>
>>
>> One other important note -- although closing a Connection is supposed to
>> close all the related Statements and ResultSets, that still doesn't help
>> if you're using a connection pool like DBCP.  The reason for this is that
>> Connection.close() simply puts the connection back into the pool -- the
>> underlying connection won't actually be closed (because that would defeat
>> the point of using a pool in the first place).  Therefore, any open
>> statements and result sets are still open (even if the JDBC driver does
>> the right thing).
> 
> 
> Craig,
> 
> I agree with everyone about closing the ResultSets and Statements and do 
> that myself.
> 
> I have just been looking at the code becuase I remember seeing that 
> DelegateConnection had a method called passivate() that does close 
> Statements and ResultSets.  I thought this was called when close()  was 
> called on the DelegateConnection, but it's not, it is called later.
> 
> The process is as follows:
> 
> 1. App gets Connection from pool
> 2. Pool provides a PoolableConnection (which extends DelegateConnection)
> 2. App uses Connection then calls close()
> 3. PoolableConnection overrides DelegateConnection's close(), because it 
> actually closes the underlying connection, and uses pool.returnObject().
> 4. GenericObjectPool.returnObject() then calls factory.passivate() on 
> the connection
> 5. PoolableConnectionFactory calls DelegateConnection.passivate() which 
> closes all of the DelegateStatements and DelegateResultSets that belong 
> to the DelegateConnection.
> 
> But looking at the code I think I found a situation where this doesn't 
> happen.  At step 4 the GenericObjectPool.returnObject() code executes 
> the following:
> 
>         if(_testOnReturn && !(_factory.validateObject(obj))) {
>             success = false;
>         } else {
>             try {
>                 _factory.passivateObject(obj);
>             } catch(Exception e) {
>                 success = false;
>             }
>         }
> 
> If we test our connections on return and the validation fails, then the 
> object will be destroyed later on with factory.destroyObject().  But 
> PoolableConnectionFactory.destroyObject() just calls 
> PoolableConnection.reallyClose() which closes the underlying connection. 
>  The passivate() code is not called and any open ResultSets and 
> Statements are never closed.
> 
> So either GenericObjectPool should be calling passivate on everything 
> returned, or DBCP's factory should call passivate when destroying 
> objects (which sounds funny).

Also I notice that GenericObjectPool.invalidateObject() also calls 
factory.destroyObject() which could also mean that those Statements and 
ResultSets are not closed.

Perhaps PoolableConnectionFactory should make destroyObject() do a 
PoolableConnection.passivate() then PoolableConnection.reallyClose()?

I suppose the GenericObjectPool thinks that the factory's destroyObject 
method should clean up everything so it doesn't need to call passivate 
on the object.



> 
> 
>>
>> Moral of the story:  ALWAYS close your statements and result sets.
>>
>>
>>> Regrettably, while the JDBC 3.0 specification formally addresses the 
>>> former
>>> case in chapter 13.1.3, it appears to be mute on the latter.
>>>
>>>
>>> Robert Egan
>>
>>
>>
>> Craig
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: commons-user-help@jakarta.apache.org
>>
>>
> 
> 

--
Jason Lea


Mime
View raw message