commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bugzi...@apache.org
Subject DO NOT REPLY [Bug 28579] New: - NumActive can become incorrect when removeAbandoned=true
Date Sun, 25 Apr 2004 09:42:28 GMT
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=28579>.
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=28579

NumActive can become incorrect when removeAbandoned=true

           Summary: NumActive can become incorrect when removeAbandoned=true
           Product: Commons
           Version: 1.1 Final
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: Normal
          Priority: Other
         Component: Dbcp
        AssignedTo: commons-dev@jakarta.apache.org
        ReportedBy: dirk.verbeeck@pandora.be


Issue & patch posted by Wayne Woodfield on commons-dev (19 April 2004)
----------------------------------------------------------------------
BUG DESCRIPTION:
I discovered this bug while using Tomcat DBCP.  I was using
removeAbandoned=true, so AbandonedObjectPool was used.  We had
maxActive=10 and maxIdle=2.  Under a really heavy load, numActive gets
off.  Over time, well over a hundred connections to the database get
spawned at the same time.  Because numActive gets so far off, it seems
like the maxActive limit is ignored.  The database runs out of
connections to give.  After the heavy load has passed and things go back
to normal, a call to DataSource.getNumActive() shows that numActive is
negative.

CAUSE:
I was able to trace this problem back to a bug in AbandonedObjectPool.
AbandonedObjectPool initiates an abandoned connection check every time
someone tries to borrow a connection from an exhausted or
nearly-exhausted connection pool.  That means that several threads could
initiate an abandoned connection sweep at once.  If two abandoned
connection checks running at the same time try to invalidate the same
connection, they will both be allowed to do so.  GenericObjectPool
(where numActive is stored) doesn't have any way of knowing whether a
connection has been invalidated before.  It just decrements numActive
again.  A connection can also be invalidated and returned to the idle
pool at the same time, again decrementing numActive twice.

AbandonedObjectPool keeps track of active connections.  When a
connection is returned or invalidated, the connection is removed from
the active list.  AbandonedObjectPool should check to see whether the
connection is still in the active list before removing it, and it
doesn't.

SOLUTION:
In AbandonedObjectPool's returnObject(Object obj) and
invalidateObject(Object obj) methods, I've added a few lines to ensure
that connections cannot be invalidated or returned twice.  Before
invalidating a connection or returning a connection to the idle pool,
I'm simply checking to see whether the connection to return or
invalidate is still in the active connection list.  If it isn't, then
this connection has already been invalidated, and the return or
invalidation is aborted.

I took advantage of the fact that calling remove(Object) on an ArrayList
returns true if the object to remove was actually found, and false
otherwise, so I didn't even have to do an additional traversal of the
active connection list to find out whether the connection had already
been removed, so there is practically no performance impact at all :-)
See the attached patch.

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


Mime
View raw message