最近几天我们在我们的网站上看到这个错误消息太多了:
“超时已过期。在从池中获取连接之前已经过了超时时间。这可能是因为所有池连接都在使用中并且达到了最大池大小。”
我们已经有一段时间没有更改代码中的任何内容了。我修改了代码以检查未关闭的打开连接,但发现一切正常。
我该如何解决这个问题?
我需要编辑这个池吗?
如何编辑此池的最大连接数?
高流量网站的推荐值是多少?
我需要在 IIS 中编辑某些内容吗?
我发现活动连接数从 15 到 31 不等,我发现 SQL 服务器中配置的最大允许连接数超过 3200 个连接,是 31 太多还是应该在 ASP.NET 配置中编辑一些东西?
在大多数情况下,连接池问题与 连接泄漏 有关。您的应用程序可能没有正确且一致地关闭其数据库连接。当您使连接保持打开状态时,它们将保持阻塞状态,直到 .NET 垃圾收集器通过调用它们的Finalize()方法为您关闭它们。
Finalize()
您要确保您 确实关闭了连接 。例如下面的代码会导致连接泄漏,如果和之间的代码.Open抛出Close异常:
.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()没有被关闭。此行不是关闭您的连接,而是创建一个新连接并尝试关闭它。
getConnection()
如果您使用SqlDataReaderor a OleDbDataReader,请关闭它们。尽管关闭连接本身似乎可以解决问题,但在使用数据读取器对象时要付出额外的努力来显式关闭它们。
SqlDataReader
OleDbDataReader
这篇来自 MSDN/SQL Magazine 的文章“为什么连接池溢出? ”解释了很多细节并提出了一些调试策略:
sp_who
sp_who2
sysprocesses
TSQL_Replay