You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by "Sandy McArthur (JIRA)" <ji...@apache.org> on 2006/05/17 05:52:06 UTC

[jira] Closed: (POOL-42) Leaking DB connections - synch problem in GenericKeyedObjectPool.returnObject()

     [ http://issues.apache.org/jira/browse/POOL-42?page=all ]
     
Sandy McArthur closed POOL-42:
------------------------------


> Leaking DB connections - synch problem in GenericKeyedObjectPool.returnObject()
> -------------------------------------------------------------------------------
>
>          Key: POOL-42
>          URL: http://issues.apache.org/jira/browse/POOL-42
>      Project: Commons Pool
>         Type: Bug

>     Versions: Nightly Builds
>  Environment: Operating System: All
> Platform: PC
>     Reporter: Anna Kreglewska
>  Attachments: sync.patch.txt, test.zip
>
> I had a problem with "leaking" database connections, using Jdbc2PoolDataSource.
> I used both commons-dbcp and commons-pool builds from 10.03.2003.
> JDK was 1.3.1_07 and 1.4.1_02 on Windows 2K, Database was Oracle 8.7.1.3 on 
> HPUX.
> The symptoms are:
> - after several minutes of test run value of _totalIdle field keeps increasing 
> (as checked with debugger)
> - the number of open database connections keeps increasing (as observed on the 
> database)
> After investigation, I discovered the problem was in 
> GenericKeyedObjectPool.returnObject().
> I belive the scenario was as follows:
> - after evictor removed idle connection, the pool was removed
> - then if a test thread wished to return a connection (returnObject()), it had 
> to recreate the pool to return the connection to
> - unfortunately sometimes the pool was recreated by more than one thread - but 
> only one stayed in _poolMap, others were discarded together with the 
> connections.
> After some changes in synchronization of returnObject(), the problem disapeared.
> My version of GenericKeyedObjectPool.returnObject():
>     public void returnObject(Object key, Object obj) throws Exception {
>         // if we need to validate this object, do so
>         boolean success = true; // whether or not this object passed validation
>         if((_testOnReturn && !_factory.validateObject(key, obj))) {
>             success = false;
>             try {
>                 _factory.destroyObject(key, obj);
>             } catch(Exception e) {
>                 // ignored
>             }
>         } else {
>             try {
>                 _factory.passivateObject(key, obj);
>             } catch(Exception e) {
>                 success = false;
>             }
>         }
>         boolean shouldDestroy = false;
>         synchronized(this) {
>             // grab the pool (list) of objects associated with the given key
>             CursorableLinkedList pool = (CursorableLinkedList) (_poolMap.get
> (key));
>             // if it doesn't exist, create it
>             if(null == pool) {
>                 pool = new CursorableLinkedList();
>                 _poolMap.put(key, pool);
>                 _poolList.add(key);
>             }
>             // subtract one from the total and keyed active counts
>             _totalActive--;
>             Integer active = (Integer) (_activeMap.get(key));
>             if(null == active) {
>                 // do nothing, either null or zero is OK
>             } else if(active.intValue() <= 1) {
>                 _activeMap.remove(key);
>             } else {
>                 _activeMap.put(key, new Integer(active.intValue() - 1));
>             }
>             // if there's no space in the pool, destroy the object
>             // else if we passivated succesfully, return it to the pool
>             if(_maxIdle > 0 && (pool.size() >= _maxIdle)) {
>                 shouldDestroy = true;
>             } else if(success) {
>                 pool.addFirst(new ObjectTimestampPair(obj));
>                 _totalIdle++;
>             }
>             notifyAll();
>         }
>         
>         if(shouldDestroy) {
>             try {
>                 _factory.destroyObject(key, obj);
>             } catch(Exception e) {
>                 // ignored?
>             }
>         }
>     }
> Please verify this.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org