连接泄漏可能导致超时过期。在从池中获取连接之前,超时时间已过。

3
我遇到了一个错误导致我的应用程序停止工作。Timeout expired.在从池中获得连接之前,超时时间已过。 这可能是因为所有池化的连接都在使用中,并且已达到最大池大小。
然而,我还没有达到我的最大连接池。我有RDS,在我的监控页面上,我发现在出现此错误时连接数为33,我的默认最大连接数为100。
因此,我想这可能是由于我的连接泄漏引起的。
这是我用来连接数据库的DBLayer类。
public static DataTable GetDataTable(SqlCommand command, IsolationLevel isolationLevel = IsolationLevel.ReadUncommitted)
{
    using (new LoggingStopwatch("Executing SQL " + command.CommandText, command.Parameters))
    {
        using (var connection = new SqlConnection(connectionString))
        using (var dataAdapter = new SqlDataAdapter(command))
        {
            command.Connection = connection;
            command.CommandTimeout = ShopexConfiguration.SqlTimeout;
            connection.Open();
            var transaction = connection.BeginTransaction(isolationLevel);
            command.Transaction = transaction;
            try
            {
                var result = new DataTable();
                dataAdapter.Fill(result);
                transaction.Commit();
                return result;
            }
            catch
            {
                try
                {
                    transaction.Rollback();
                }
                catch (Exception)
                {
                    //
                    // This catch block will handle any errors that may have occurred 
                    // on the server that would cause the rollback to fail, such as 
                    // a closed connection.
                }
                throw;
            }
        }
    }
}

我想知道,这会导致连接泄漏吗?

我看过这篇博客:

https://blogs.msdn.microsoft.com/spike/2008/08/25/timeout-expired-the-timeout-period-elapsed-prior-to-obtaining-a-connection-from-the-pool/

任何帮助都是受欢迎的?

这可能是一个冒险的尝试,但是在服务器上每个用户打开连接的数量是否有限制? - Kris Vandermotten
2个回答

1

您确定您的查询没有达到执行超时吗?SqlConnection.ConnectionTimeout 的默认值为15秒

另外,在您的connectionString中是否有一些连接超时值,格式为:"....;Connection Timeout=10..."


1
不,这不是超时问题,我之前遇到过超时问题,但我的应用程序一直运行良好。当我遇到这个异常时,即使 elmah 也无法记录错误,我不得不使用 new relic 来获取错误详细信息。 - user123456

1
我认为你应该在finally语句中关闭你的连接,就像下面这样:
public static DataTable GetDataTable(SqlCommand command, IsolationLevel isolationLevel = IsolationLevel.ReadUncommitted)
{
    using (new LoggingStopwatch("Executing SQL " + command.CommandText, command.Parameters))
    {
        using (var connection = new SqlConnection(connectionString))
        using (var dataAdapter = new SqlDataAdapter(command))
        {
            command.Connection = connection;
            command.CommandTimeout = ShopexConfiguration.SqlTimeout;
            connection.Open();
            var transaction = connection.BeginTransaction(isolationLevel);
            command.Transaction = transaction;
            try
            {
                var result = new DataTable();
                dataAdapter.Fill(result);
                transaction.Commit();
                return result;
            }
            catch
            {
                try
                {
                    transaction.Rollback();
                }
                catch (Exception)
                {
                    //
                    // This catch block will handle any errors that may have occurred 
                    // on the server that would cause the rollback to fail, such as 
                    // a closed connection.
                }
                finally { connection.Close(); }
                throw;
            }
        }
    }
}

也许它可以解决您的问题,因为您在catch语句中回滚事务时没有关闭现有连接,您还可以在打开SQL连接之前使用以下条件:
    if (connection.State == ConnectionState.Closed) {
        // Open your connection here
        connection.Open();
    }
// Do your logic here

希望这能对你有所帮助。

谢谢


@sunul Kamur 谢谢您的回答,我正在考虑这样做。但我原本以为 transaction.Rolleback 应该会自动关闭连接。 - user123456
如果我的解决方案对您有帮助,请标记并点赞,谢谢 :) - Sunil Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接