让 .net SqlConnection 无限期打开与 using 块

我有一个深入的问题。我想了解为什么 aSqlConnection被关闭以及如何检测连接池是否实际发生。


我有两个不同版本的类,它们抽象与数据库对话并返回DataTable. 我提供的是问题/疑问的示例。


版本 1SqlConnection在实例化时打开 a 并将其保持打开状态。这是一个单线程进程,它处理传入消息并将结果尽快写入数据库。这就是永久开放背后的想法SqlConnection:


public class SpecialDbClientVersion1 : IDisposable

{

    string connStr;

    SqlConnection dbConn;


    public SpecialDbClientVersion1(string connStr)

    {

        this.connStr = connStr;

        this.dbConn = new SqlConnection(connStr);


        try

        {

            dbConn.Open();

        }

        catch (SqlException ex)

        {

            throw new Exception($"An exception occurred while trying to connect to {dbConn.Database}", ex);

        }

    }


    public DataTable QuerySqlReturnResultAsDataTable(string sql, int commandTimeout = 30)

    {

        try

        {

            var cmd = new SqlCommand(sql, dbConn);

            cmd.CommandType = CommandType.Text;

            cmd.CommandTimeout = commandTimeout;

            var dt = new DataTable();

            var adapter = new SqlDataAdapter(cmd);

            adapter.Fill(dt);

            return dt;

        }

        catch (Exception e)

        {

            throw new InvalidOperationException(e.Message);

        }

    }


    public void Dispose()

    {

        dbConn.Dispose();

    }

}

当我测试这个时,一切都很顺利,并且吞吐量非常高。最终由于SqlConnection某种原因关闭了。抛出一个错误,聚会就结束了。


问题 1Closed :有人可以解释一下,在我不调用该方法的情况下,什么会导致此连接进入某种状态Close()吗?


现在版本 2 在一个块中执行所有工作using。根据互联网,运行时应该神奇地在幕后使用连接池。SqlConnection这是Microsoft处理对象的最佳实践。使用连接池应该不会对性能造成太大影响。


public class SpecialDbClientVersion2

{

    string connStr;

    SqlConnection dbConn;


    public SpecialDbClientVersion2(string connStr)

    {

        this.connStr = connStr;

    }

问题2:如何判断连接池是否真正被使用?写入数据库需要尽可能快,我担心版本 2 每次都必须重新建立与数据库的连接。这会破坏性能。如何衡量是否发生连接池以及它是否影响服务的吞吐量?


我一直在寻找关于这个主题的深入研究资源,但我发现的大部分内容只是“在块中使用 SqlConnection using,一切都会好起来的”。我正在寻找比这更深入的解释。我真的很想了解这里发生的事情的本质,以便我找到正确的性能问题。感谢您提供的任何见解。


守候你守候我
浏览 84回答 1
1回答

跃然一笑

正如其他人提到的,连接可能在服务器端关闭或由于空闲超时而关闭,请检查服务器端日志以了解详细信息。对于问题的第二部分,有一些性能计数器可以跟踪连接池信息。NumberOfPooledConnections这可以通过代码查看(请参阅链接页面的示例),设置正在运行的程序的进程 ID 并显示诸如和 之类的值,NumberOfNonPooledConnections以查看连接池是否确实被进程使用。通过打开默认关闭的计数器,您还可以监视NumberOfFreeConnections它,它会告诉您是否有免费的开放连接可供您的程序拾取并使用以获得立即响应,而无需打开您要求的连接的开销。
打开App,查看更多内容
随时随地看视频慕课网APP