[译]连接池和 "Timeout expired"异常
作者:admin 日期:2008-11-27
原文标题:Connection Pooling and the "Timeout expired" exception FAQ
来源:http://blogs.msdn.com/angelsb/archive/2004/08/25/220333.aspx
作者:angelsb
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.
Timeout expired 异常是个很棘手的异常,想必几乎每个人都碰到过。有时可真是对它咬牙切齿,拿它没办法。 angelsb这篇文章很好,希望对大家有用。我也是看到他讲得很好,才翻译过来的,水平有限,请多多指教.
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.
哎!在另一个进程中,又出现了连接池已满的问题,这是个最让人头痛却又是最常出现的连接池问题之一.原因是在开发过程中很少碰到这个头痛的问题,但在部署APP到客户端时,却总是不经意地跑出来了.我想,我应该花些许时间对这个问题进行一次完整的总结吧.
发生的本质是什么?
我们来认真看一下可能会发生这种异常的两种情况
1) 你使用了超过最大的连接池连接数(默认的最大连接数是100)
在大部分应用程序中,这种情况是很少出现的. 毕竟当你使用连接池时,100个并行连接是一个非常大的数字.根据我的经验,会造成这种异常的原因的最大可能,应该是在一个纯种下打开了100个连接.
SqlConnection[] connectionArray = new SqlConnection[101];
for (int i = 0; i <= 100; i++)
{
connectionArray = new SqlConnection("Server=.\\SQLEXPRESS ;Integrated security=sspi;connection timeout=5");
connectionArray[i].Open();
}
解决方案:如果你确定你将会使用超过100个并行连接(在同一连接字符串上),你可以增加最大连接数.
2) 连接泄漏
我个人认为的连接泄漏定义是你打开了一个连接但你没有在你的代码中执行close()或dispose().这范围不仅仅是你忘记了在connection后连接后使用dispose()或close()对期进行关闭,还包括一些你已经在相关connection后写好了close()却根本没有起作用的情況.我们来看看下面的代码:
using System;
using System.Data;
using System.Data.SqlClient;
public class Repro
{
public static int Main(string[] args)
{
Repro repro = new Repro();
for (int i = 0; i <= 5000; i++)
{
try{ Console.Write(i+" "); repro.LeakConnections(); }
catch (SqlException){}
}
return 1;
}
public void LeakConnections()
{
SqlConnection sqlconnection1 = new SqlConnection("Server=.\\SQLEXPRESS ;Integrated security=sspi;connection timeout=5");
sqlconnection1.Open();
SqlCommand sqlcommand1 = sqlconnection1.CreateCommand();
sql...[/i]
来源:http://blogs.msdn.com/angelsb/archive/2004/08/25/220333.aspx
作者:angelsb
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.
Timeout expired 异常是个很棘手的异常,想必几乎每个人都碰到过。有时可真是对它咬牙切齿,拿它没办法。 angelsb这篇文章很好,希望对大家有用。我也是看到他讲得很好,才翻译过来的,水平有限,请多多指教.
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.
哎!在另一个进程中,又出现了连接池已满的问题,这是个最让人头痛却又是最常出现的连接池问题之一.原因是在开发过程中很少碰到这个头痛的问题,但在部署APP到客户端时,却总是不经意地跑出来了.我想,我应该花些许时间对这个问题进行一次完整的总结吧.
发生的本质是什么?
我们来认真看一下可能会发生这种异常的两种情况
1) 你使用了超过最大的连接池连接数(默认的最大连接数是100)
在大部分应用程序中,这种情况是很少出现的. 毕竟当你使用连接池时,100个并行连接是一个非常大的数字.根据我的经验,会造成这种异常的原因的最大可能,应该是在一个纯种下打开了100个连接.
复制内容到剪贴板 程序代码
SqlConnection[] connectionArray = new SqlConnection[101];
for (int i = 0; i <= 100; i++)
{
connectionArray = new SqlConnection("Server=.\\SQLEXPRESS ;Integrated security=sspi;connection timeout=5");
connectionArray[i].Open();
}
解决方案:如果你确定你将会使用超过100个并行连接(在同一连接字符串上),你可以增加最大连接数.
2) 连接泄漏
我个人认为的连接泄漏定义是你打开了一个连接但你没有在你的代码中执行close()或dispose().这范围不仅仅是你忘记了在connection后连接后使用dispose()或close()对期进行关闭,还包括一些你已经在相关connection后写好了close()却根本没有起作用的情況.我们来看看下面的代码:
复制内容到剪贴板 程序代码
using System;
using System.Data;
using System.Data.SqlClient;
public class Repro
{
public static int Main(string[] args)
{
Repro repro = new Repro();
for (int i = 0; i <= 5000; i++)
{
try{ Console.Write(i+" "); repro.LeakConnections(); }
catch (SqlException){}
}
return 1;
}
public void LeakConnections()
{
SqlConnection sqlconnection1 = new SqlConnection("Server=.\\SQLEXPRESS ;Integrated security=sspi;connection timeout=5");
sqlconnection1.Open();
SqlCommand sqlcommand1 = sqlconnection1.CreateCommand();
sql...