Bug #17338 Deadlock when using connecton pooling
Submitted: 13 Feb 2006 6:10 Modified: 18 Apr 2006 8:17
Reporter: Vincent Ong Email Updates:
Status: Can't repeat Impact on me:
None 
Category:Connector / NET Severity:S2 (Serious)
Version:1.0 OS:Microsoft Windows (Windows XP Pro SP2)
Assigned to: CPU Architecture:Any

[13 Feb 2006 6:10] Vincent Ong
Description:
When more process threads than the number of maximum connections specified for connection pooling are trying to access the MySQL database simultaneously, the connector went in to a (almost) deadlock situation and the application hangs.

The problem occurs due to the need to acquire locks such as pools.SyncRoot for both GetConnection() and ReleaseConnection(). 

When the maximum number of connections has been issued, the next process thread, A, will obtain the lock and stay inside the function GetConnection() until a connection is available or a timeout occur. 

However, while doing so, a process which wanted to release the connection found that it cannot obtain the lock anymore since it is actually taken by process thread A and thus all threads started waiting for each other.

How to repeat:
Specify a maximum number of connections allows in the connection string such as 

Server=localhost;port=3306;Database=myDB;uid=user;pwd=password;Pooling=true;Max Pool Size=80;Min Pool Size=20;Connection Timeout=5

Create an application where 100 threads are trying to access the database using the connector at the same time. 

The connector will go into a deadlock situation. 

Suggested fix:
At the MySqlPoolManager, initialise the pool hashtable as
	pools = Hashtable.Synchronized(new Hashtable());

and remove the lock, lock (pools.SyncRoot), for ReleaseConnection( Driver driver ).

This will allow any processes wanting to release the connections to access the function without waiting for the lock (which causes the deadlock situation.

Same goes for the MySqlPool, initialise as
             inUsePool = ArrayList.Synchronized(new ArrayList(maxSize));
	idlePool = Queue.Synchronized(new Queue(maxSize));

and remove the locks, lock (idlePool.SyncRoot) and lock (inUsePool.SyncRoot), for ReleaseConnection( Driver driver ).

-------------------------------------------------------

After this modifcation, my application works smoothly without hanging as experience before. I hope this works and is useful for you. Cheers!
[18 Apr 2006 8:17] Tonci Grgin
Hi. Thanks for your problem report. There is no deadlock with newer version of Connector_NET.