Connections in pool not being reused

D

David Kirkman

I have a C# Windows Forms app. (Framework 1.1 VS 2003) using a SQL
Server 2K database. It appears that despite closing and disposing all
connections immediately after use and always using the same connection
string the connections in the connection pool are not being reused.
When the code attempts to open the 100th connection, the following
exception is thrown:

System.InvalidOperationException: Timeout expired. The timeout period
elapsed prior to obtaining a connection from the pool. This may have
occurred because all pooled connections were in use and max pool size
was reached.

Using SQL Enterprise manager it can be seen that the connections are
indeed being closed i.e there is only ever one connection open - so
what is going on? According to everything I have read about connection
pooling, the connections should be stored in the pool when they are
closed and if an attempt is made to open a new one with the same
connection string, a connection in the pool is used.

Here is some code which uses Northwind so anyone can run it. Just
create a form and put a button on it, You will need to make sure that
the Output window is visible in VS:

private DataSet GetDataSetSql(string sqlString)
{
string cnString = "server=" + "Put your server name here" +
";Trusted_Connection=yes; database=Northwind";
SqlConnection cn;

try
{
cn = new SqlConnection (cnString);
cn.Open();
SqlDataAdapter da = new SqlDataAdapter(sqlString, cn);
DataSet ds = new DataSet();
da.Fill(ds);
cn.Close();
cn.Dispose();
return ds;

}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
Console.Write(ex.ToString());
return null;
}

}

private void button1_Click(object sender, System.EventArgs e)
{
string sql;
DataSet ds;

for (int x = 10247; x < 10447; x++)
{
sql = "select orderid from orders where orderid = " +
x.ToString();
ds = GetDataSetSql(sql);
Console.Write(x.ToString() + "\n");
}
}

On my machine the OrderIDs are shown in the output window up to 10346
(the 99th order in the table) it then fails. I would be interested to
know if this behaviour occurs for others. I have tried increasing the
Pool size in the connection string and this allows more connections to
be made but there should be no need to do this as 100 should be more
than enough.
 
W

William \(Bill\) Vaughn

I looked at the code and didn't see anything egregious. I do know that
you're doing more work than you need to. Remove the Open, Close and Dispose.
All of these are handled by the Fill.
I would also look elsewhere for the problem. If this is all of your code
then I don't understand why it's not working. Your assessment of how the
connection pool works is correct. The symptom you're seeing is when the
connection is not closed or still in use (results pending) when the Open
occurs.
Note that the connection pool has a very minor role to play in a Windows
Forms (smart client) application. I generally open the connection and leave
it open for the life of the application. Sure, I might timeout the
connection after so many minutes of idle time, but not always. By using a
single connection, you'll uncover pending results issues that might be part
of your problem.

hth

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
 
M

Miha Markic [MVP C#]

Hi Bill,

William (Bill) Vaughn said:
I looked at the code and didn't see anything egregious. I do know that
you're doing more work than you need to. Remove the Open, Close and
Dispose. All of these are handled by the Fill.
I would also look elsewhere for the problem. If this is all of your code
then I don't understand why it's not working. Your assessment of how the
connection pool works is correct. The symptom you're seeing is when the
connection is not closed or still in use (results pending) when the Open
occurs.
Right.

Note that the connection pool has a very minor role to play in a Windows
Forms (smart client) application. I generally open the connection and
leave it open for the life of the application. Sure, I might timeout the
connection after so many minutes of idle time, but not always. By using a
single connection, you'll uncover pending results issues that might be
part of your problem.

I wonder why are you taking this approach, I mean I can think of at least
two of the downsides:
- troubles for multithreading (of course, it doesn't matter if you don't do
multithread database access)
- if connection errors then you explicitly need to re-open it
Generally I prefer open JIT and close ASAP.
 
W

William \(Bill\) Vaughn

Multithreading is possible--just open as many connections as needed--closing
those you don't need. Connection exception handling is centralized on
initial connection and routed to a common state-machine handler when
operations fail due to connection issues.

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
 
D

David Kirkman

Keeping the connection open is an interesting idea, as a relative
newcomer to .NET, I had got the impression from a number of sources
that the connection should be opened for as short a time as possible so
it is interesting to hear a recognised expert in the field suggest
this. Could there be a problem with SQL licences? I will certainly
consider this approach, but I would like to understand why the
connection pooling does not appear to work. I have now tried the code I
supplied in the first post on three different machines (one using a
local copy of the database) with the same result.

Is it a bug, perhaps introduced via a service pack?

I guess many people on this forum have upgraded to .NET 2.0 but if
anyone is still on 1.1 can you please try my Northwind example. If you
don't have the same problem then there must be something else that I am
doing wrong but I can't imagine what it could be with such a simple
example.

I don't understand how there can be results still pending on the
connection as it is only returning one record to the DataSet which it
appears to do successfully. Examining the locals window when stepping
through the code I see that the _internalConnection._pool.connections
ArrayList gradually increases to the max pool size, however when I use
the Performance monitor the SqlClient Current # pooled connections
counter never gets above 1. This counter drops to zero each time the
debugger steps past the cn.Close() line.
 
W

William \(Bill\) Vaughn

Many of the books (esp. the early ones) focused on ASP architectures. Smart
client has just been "reborn" and the older (wiser and experienced)
architectures are being brought back to life. Keeping a connection open
limits scalability--to several hundred to a few thousand users. Yes, there
are some licensing issues but the connection pool approach does not really
impact that if I read the license right.
I worked with 1.0 and 1.1 for ages and never saw this issue--unless
something else was opening connections and leaving them open. I would use
the profiler to track down what process is doing it and when.

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
 
D

David Kirkman

Thanks for your help Bill
I have finally cracked it - a few months ago I attempted (unsuccesfully
- but that is another story) to debug a stored procedure in VS .NET and
set the 'Enable SQL Debugging' Configuration property for the project
in question to true. If I set this property to false the connection
pool problem disappears.
 
W

William \(Bill\) Vaughn

Ah. I keep forgetting to tell people about that. It's the price of getting
old I guess.
I'm glad you got it working.

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top