有连接池保持打开状态的问题(显式关闭连接)
本文关键字:连接 问题 状态 | 更新日期: 2023-09-27 18:12:03
我的应用程序出现了一个错误,认为已达到最大池大小:
超时过期。从池中获取连接之前的超时时间。这可能是因为所有池连接都在使用中,并且已达到最大池大小。
我们有一个内部函数,它返回一个DataReader
。在这个函数内部,我们使用ExecuteReader
方法,它被赋值为CommandBehavior.CloseConnection
。在读取了我们需要的数据之后,我们在该函数返回的DataReader
上调用.Close
和.Dispose
。
在旁注上,我还尝试实现一种不同的方法,其中我在连接上做了using
标签,并且仍然将其视为数据库中的"睡眠"。
我运行下面的查询来获取仍处于睡眠状态的连接。在任何时候,我们都能看到大约40个左右的人被列为"睡觉"。我抓住这里使用的SQL脚本,将其追溯到它们在应用程序中使用的地方,并三重检查DataReader
正在关闭。
SELECT sp.spid, sp.hostname, sp.program_name, sp.loginame, sp。login_time, sp.status, CAST(text AS VARCHAR(1000)) AS SQLScript从系统。sysprocesses sp CROSS APPLY sys.dm_exec_sql_text(sp.sql_handle) where program_name='。. Net SqlClient数据提供程序'和loginname ='[LoginNameForSql]' order by SQLScript
我还需要做些什么来确保这些连接被关闭吗?我们的团队非常困惑,因为我们所有人都在使用后再三检查我们的阅读器是否关闭并处理。
获取数据阅读器的函数:
SqlConnection conn = OpenConnection(); SqlDataReader rdr = null; // try // { SQL = strSQL; CommandBehavior intBehavior = CommandBehavior.CloseConnection; using (var cmd = conn.CreateCommand()) { cmd.CommandText = strSQL; cmd.CommandTimeout = Timeout; rdr = cmd.ExecuteReader(intBehavior); cmd.Parameters.Clear(); } return rdr;
使用上述函数:
var rdr = FunctionReturningDataReader(); if (rdr != null) { if (rdr.HasRows) { while (rdr.Read()) { } } } rdr.Close(); rdr.Dispose();
编辑:我将最大池大小增加到200,并且自3天前以来没有在我们的应用程序中看到此错误。
我担心的是,您正在关闭连接,但它没有超出范围并被处理(快速?)。
我没有看到FunctionReturningDataReader()增加了那么多的值。
不要浪费时间——尽可能晚地打开连接,尽可能早地关闭和处理连接。
我会在行中这样做,并将SQLconnection放在using中。
SqlDataReader
private static void ReadOrderData(string connectionString)
{
string queryString =
"SELECT OrderID, CustomerID FROM dbo.Orders;";
using (SqlConnection connection =
new SqlConnection(connectionString))
{
SqlCommand command =
new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// Call Read before accessing data.
while (reader.Read())
{
ReadSingleRow((IDataRecord)reader);
}
// Call Close when done reading.
reader.Close();
}
}
我的答案被投票否决了,因为没有把reader放在using
这是来自文档的,我发现reader.Close()已经足够了
如果你觉得有必要把reader放到using
确保您还关闭了Database Connection对象,而不仅仅是DataReader。打开数据库连接将填满连接池