最近几天我们在网站上看到这条错误消息:
"超时已到期.在从池中获取连接之前已经过了超时时间.这可能是因为所有池连接都在使用中并且达到了最大池大小."
我们的代码暂时没有改变任何内容.我修改了代码以检查未关闭的打开连接,但发现一切都很好.
我怎么解决这个问题?
我需要编辑此池吗?
如何编辑此池的最大连接数?
高流量网站的推荐值是多少?
我需要在IIS中编辑某些内容吗?
我发现活动连接的数量在15到31之间,我发现在SQL Server中配置的最大允许连接数超过3200个连接,31个太多,或者我应该在ASP.NET配置中编辑一些东西?
在大多数情况下,连接池问题与"连接泄漏"有关.您的应用程序可能无法正确且一致地关闭其数据库连接.当您打开连接时,它们将保持阻塞状态,直到.NET垃圾收集器通过调用其Finalize()
方法为您关闭它们.
您想确保您确实关闭了连接.例如,下面的代码将导致一个连接泄漏,如果之间的代码.Open
和Close
抛出异常:
var connection = new SqlConnection(connectionString);
connection.Open();
// some code
connection.Close();
正确的方法是:
var connection = new SqlConnection(ConnectionString);
try
{
connection.Open();
someCall (connection);
}
finally
{
connection.Close();
}
要么
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
someCall(connection);
}
当您的函数从类方法返回连接时,请确保在本地缓存它并调用其Close
方法.您将使用此代码泄漏连接,例如:
var command = new OleDbCommand(someUpdateQuery, getConnection());
result = command.ExecuteNonQuery();
connection().Close();
第一次调用返回的连接getConnection()
未关闭.此行不是关闭您的连接,而是创建一个新的并尝试关闭它.
如果您使用SqlDataReader
或a OleDbDataReader
,请关闭它们.即使关闭连接本身似乎也可以解决问题,但在使用它们时需要额外的努力来明确地关闭数据读取器对象.
MSDN/SQL杂志上的这篇文章" 为什么连接池溢出? "解释了很多细节并提出了一些调试策略:
跑sp_who
或sp_who2
.这些系统存储过程从sysprocesses
系统表返回信息,该信息显示所有工作进程的状态和信息.通常,您将看到每个连接一个服务器进程ID(SPID).如果使用连接字符串中的"应用程序名称"参数命名连接,则可以轻松找到工作连接.
将SQL Server Profiler与SQLProfiler TSQL_Replay
模板一起使用以跟踪打开的连接.如果您熟悉Profiler,则使用sp_who比使用轮询更容易.
使用性能监视器来监视池和连接.我马上讨论这个方法.
在代码中监视性能计数器.您可以使用例程提取计数器或使用新的.NET PerformanceCounter控件来监视连接池的运行状况和已建立连接的数量.
安装.NET Framework v4.6.1后,由于此更改,我们与远程数据库的连接立即开始超时.
要修复,只需TransparentNetworkIPResolution
在连接字符串中添加参数并将其设置为false:
服务器= myServerName;数据库= MyDatabase的; Trusted_Connection = TRUE; TransparentNetworkIPResolution =假
除非您的使用量增加,否则似乎不太可能存在积压的工作.IMO,最可能的选择是某些东西正在使用连接而不是立即释放它们.你确定你using
在所有情况下都在使用吗?或者(通过什么机制)释放连接?
在关闭连接或datareader之前,您是否检查过未关闭的DataReader和response.redirects?在重定向之前不关闭它们时,连接会保持打开状态.
我们也经常在我们的网站上遇到这个问题.在我们的案例中,罪魁祸首是我们的统计/指数已经过时.这导致先前快速运行的查询(最终)变慢和超时.
尝试更新统计信息和/或重建受查询影响的表上的索引,看看是否有帮助.
您可以通过在连接字符串中指定MinPoolSize=xyz
和/或指定最小和最大池大小MaxPoolSize=xyz
.然而,这个问题的原因可能是另一回事.
在我的一个.NET应用程序中使用某些第三方数据层时,我也遇到过这个问题.问题是该层没有正确关闭连接.
我们抛出了图层并自己创建了一个图层,它总是关闭并处理连接.从那时起,我们不再得到错误.
您也可以尝试解决超时问题:
如果您没有将httpRuntime添加到您的webconfig中,请在
标记中添加
和
像这样修改您的连接字符串;
最后使用
try {...} catch {...} finaly { connection.close(); }