小编典典

如何解决 ASP.NET 和 SQL Server 之间的连接池问题?

all

最近几天我们在我们的网站上看到这个错误消息太多了:

“超时已过期。在从池中获取连接之前已经过了超时时间。这可能是因为所有池连接都在使用中并且达到了最大池大小。”

我们已经有一段时间没有更改代码中的任何内容了。我修改了代码以检查未关闭的打开连接,但发现一切正常。

  • 我该如何解决这个问题?

  • 我需要编辑这个池吗?

  • 如何编辑此池的最大连接数?

  • 高流量网站的推荐值是多少?


更新:

我需要在 IIS 中编辑某些内容吗?

更新:

我发现活动连接数从 15 到 31 不等,我发现 SQL 服务器中配置的最大允许连接数超过 3200 个连接,是 31 太多还是应该在 ASP.NET
配置中编辑一些东西?


阅读 142

收藏
2022-05-18

共1个答案

小编典典

在大多数情况下,连接池问题与 连接泄漏 有关。您的应用程序可能没有正确且一致地关闭其数据库连接。当您使连接保持打开状态时,它们将保持阻塞状态,直到
.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()没有被关闭。此行不是关闭您的连接,而是创建一个新连接并尝试关闭它。

如果您使用SqlDataReaderor a
OleDbDataReader,请关闭它们。尽管关闭连接本身似乎可以解决问题,但在使用数据读取器对象时要付出额外的努力来显式关闭它们。


这篇来自 MSDN/SQL Magazine 的文章“为什么连接池溢出? ”解释了很多细节并提出了一些调试策略:

  • 运行sp_whosp_who2。这些系统存储过程从sysprocesses系统表中返回信息,显示所有工作进程的状态和信息。通常,您会看到每个连接都有一个服务器进程 ID (SPID)。如果您使用连接字符串中的应用程序名称参数命名您的连接,您的工作连接将很容易找到。
  • 使用带有 SQLProfilerTSQL_Replay模板的 SQL Server Profiler 来跟踪打开的连接。如果您熟悉 Profiler,则此方法比使用 sp_who 轮询更容易。
  • 使用性能监视器来监视池和连接。我马上讨论这个方法。
  • 监控代码中的性能计数器。您可以通过使用例程提取计数器或使用新的 .NET PerformanceCounter 控件来监视连接池的运行状况和已建立的连接数。
2022-05-18