最近几天我们在我们的网站上看到太多这样的错误消息:
"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."
我们已经有一段时间没有更改代码中的任何内容了。我修改了代码来检查未关闭的打开连接,但发现一切都很好。
如何解决这个问题?
我需要编辑此池吗?
如何编辑此池的最大连接数?
高流量网站的建议值是多少?
更新:
我需要在 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
或OleDbDataReader
,请关闭它们。尽管关闭连接本身似乎可以解决问题,但在使用数据读取器对象时,请付出额外的努力来显式关闭它们。
MSDN/SQL 杂志的这篇文章“Why Does a Connection Pool Overflow?”解释了很多细节并提出了一些调试策略:
- 运行
sp_who
或sp_who2
。这些系统存储过程从sysprocesses
系统表返回信息,该表显示所有工作进程的状态和信息。通常,每个连接您都会看到一个服务器进程 ID (SPID)。如果您使用连接字符串中的应用程序名称参数来命名连接,则可以轻松找到您的工作连接。 - 使用 SQL Server Profiler 和 SQLProfiler
TSQL_Replay
模板来跟踪打开的连接。如果您熟悉 Profiler,此方法比使用 sp_who 进行轮询更容易。 - 使用性能监视器来监视池和连接。我稍后会讨论这个方法。
- 监控代码中的性能计数器。您可以通过使用例程提取计数器或使用新的 .NET PerformanceCounter 控件来监视连接池的运行状况以及已建立的连接数。
关于.net - 如何解决 ASP.NET 和 SQL Server 之间的连接池问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/670774/