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