连接池保持打开时出现问题(明确关闭连接)

时间:2014-07-08 14:25:31

标签: c# sql .net sql-server sql-server-2012

我的应用程序出现了一个错误,即达到了最大池大小:

  

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

我们有一个返回DataReader的内部函数。在此函数内部,我们使用ExecuteReader方法,该方法的值为CommandBehavior.CloseConnection。在阅读了我们需要的数据后,我们在.Close上调用此函数返回的.DisposeDataReader

另外,我还尝试实现一种不同的方法,在该方法中我在我的连接上执行了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   FROM sys.sysprocesses sp CROSS APPLY sys.dm_exec_sql_text   (sp.sql_handle)其中program_name ='。Net SqlClient Data Provider'和   loginame ='[LoginNameForSql]'按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天前我们的应用程序中没有看到此错误。

2 个答案:

答案 0 :(得分:0)

确保您还关闭了数据库连接对象,而不仅仅是DataReader。打开与数据库的连接将填满您的连接池。

答案 1 :(得分:0)

我担心的是你正在关闭连接,但它不会超出范围并被处理(快速?)。

我没有看到FunctionReturningDataReader()增加了那么多值 不要愚弄 - 尽可能晚地打开连接并关闭它并尽早处理它 我会这样做,并将SQL连接放入使用。
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.Close()就足够了 如果你觉得有必要让读者使用,那么就这样做