commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Phil Steitz (JIRA)" <>
Subject [jira] Commented: (DBCP-65) [dbcp] Deadlock when evicting dbcp objects (testWhileIdle=true)
Date Thu, 21 Dec 2006 04:50:23 GMT
    [ ] 
Phil Steitz commented on DBCP-65:

Unless someone can give a good reason that PoolingConnection's prepareStatement methods *must*
be synchronized, I am inclined to remove the synchronization from these methods.  That sounds
radical, but observe that all we have in these methods is:q
try {
        } catch(NoSuchElementException e) {
            throw new SQLNestedException("MaxOpenPreparedStatements limit reached", e); 
        } catch(RuntimeException e) {
            throw e;
        } catch(Exception e) {
            throw new SQLNestedException("Borrow prepareStatement from pool failed", e);
The borrowObject pool method is synchronized and the cause of the deadlocks here and in DBCP-202
is that these methods lock the PoolingConnection first and then the pool.   I thought first
about changing the order explicitly by replacing the outer synchronization with 
synchronized (_pstmtPool) {
  synchronized (this) {
to force consistent lock order, but then could not see any reason for the inner synch, and
the other one is already there in the pool method.  
Can anyone see why these methods need to be synchronized on the PoolingConnection?   If this
seems too high-risk, how about the explicit lock ordering above?
Removing or altering synchronization lock order should resolve DBCP-202 as well.

> [dbcp] Deadlock when evicting dbcp objects (testWhileIdle=true)
> ---------------------------------------------------------------
>                 Key: DBCP-65
>                 URL:
>             Project: Commons Dbcp
>          Issue Type: Bug
>         Environment: Operating System: All
> Platform: All
>            Reporter: Wang Xianzhu
>             Fix For: 1.3
> The GenericKeyedObjectPool$Evictor thread has probability of deadlock with dbcp
> objects.
> For example, at a certain time, a normal user thread calls a PoolingConnection
> object's synchronized method, which in turn calls GenericKeyedObjectPool
> object's synchronzied method.
> At the same time, the evictor thread calls the GenericKeyedObjectPool object's
> synchronized method 'evict', which in turn calls the PoolingConnection object's
> synchronized method.  When testWhileIdle=true, the probability of evictor
> calling GenericKeyedObjectPool's synchronized method is much greater.
> The following is the deadlock information in the thread dump of our program
> (testWhileIdle=true):
> "Thread-106":
> 	at org.apache.commons.dbcp.AbandonedTrace.removeTrace(
> 	- waiting to lock <0x6a6b1b80> (a org.apache.commons.dbcp.PoolingConnection)
> 	at
> org.apache.commons.dbcp.PoolablePreparedStatement.passivate(
> 	at
> org.apache.commons.dbcp.PoolingConnection.passivateObject(
> 	at
> org.apache.commons.pool.impl.GenericKeyedObjectPool.evict(
> 	- locked <0x6a6b1858> (a org.apache.commons.pool.impl.GenericKeyedObjectPool)
> 	at
> org.apache.commons.pool.impl.GenericKeyedObjectPool$
> 	at
> "Thread-41":
> 	at
> org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(
> 	- waiting to lock <0x6a6b1858> (a
> org.apache.commons.pool.impl.GenericKeyedObjectPool)
> 	at
> org.apache.commons.dbcp.PoolingConnection.prepareStatement(
> 	- locked <0x6a6b1b80> (a org.apache.commons.dbcp.PoolingConnection)
> 	at
> org.apache.commons.dbcp.DelegatingConnection.prepareStatement(
> 	at
> org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareStatement(
> ...
> This problem can be worked around by setting testWhileIdle to false, although
> there is still very small possibility of deadlock.

This message is automatically generated by JIRA.
If you think it was sent incorrectly contact one of the administrators:
For more information on JIRA, see:


To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message