繁体   English   中英

“打开/关闭”SqlConnection 还是保持打开状态?

[英]“open/close” SqlConnection or keep open?

我在带有静态方法的简单静态类中实现了我的业务逻辑。 这些方法中的每一个在调用时都会打开/关闭 SQL 连接:

public static void DoSomething()
{
    using (SqlConnection connection = new SqlConnection("..."))
    {
        connection.Open();

        // ...

        connection.Close();
    }
}

但我认为避免打开和关闭连接可以节省性能 我很久以前用OleDbConnection类做了一些测试(不确定 SqlConnection),它确实有助于像这样工作(据我所知):

//pass around the connection object into the method
public static void DoSomething(SqlConnection connection)
{
    bool openConn = (connection.State == ConnectionState.Open);
    if (!openConn)
    {
        connection.Open();
    }

    // ....

    if (openConn) 
    {
        connection.Close();
    }
}

所以问题是 - 我应该选择方法(a)还是方法(b)? 我在另一个 stackoverflow 问题中读到连接池为我节省了性能,我根本不必费心......

附注。 这是一个 ASP.NET 应用程序 - 连接仅在 Web 请求期间存在。 不是一个成功的应用程序或服务。

坚持选项 a

连接池是您的朋友。

每次都使用方法 (a)。 当您开始扩展应用程序时,如果不这样做,处理状态的逻辑将变得非常痛苦。

连接池做它在锡上所说的。 想想当应用程序扩展时会发生什么,以及手动管理连接打开/关闭状态会有多困难。 连接池在自动处理这个方面做得很好。 如果您担心性能,请考虑某种内存缓存机制,以便不会被阻塞。

一旦完成连接,请始终关闭它们,因此它们的底层数据库连接可以返回到池中并可供其他调用者使用。 连接池经过了很好的优化,因此这样做没有明显的损失。 建议基本上与交易相同 - 保持简短并在您完成后关闭。

如果您通过围绕使用多个连接的代码使用单个事务而遇到 MSDTC 问题,情况会变得更加复杂,在这种情况下,您实际上必须共享连接对象,并且只有在事务完成后才关闭它。

但是,您在这里是手工操作的,因此您可能需要研究为您管理连接的工具,例如 DataSet、Linq to SQL、Entity Framework 或 NHibernate。

免责声明:我知道这是旧的,但我找到了一个简单的方法来证明这个事实,所以我投入了我的两美分。

如果您无法相信池化真的会更快,那么试试这个:

在某处添加以下内容:

using System.Diagnostics;
public static class TestExtensions
{
    public static void TimedOpen(this SqlConnection conn)
    {
        Stopwatch sw = Stopwatch.StartNew();
        conn.Open();
        Console.WriteLine(sw.Elapsed);
    }
}

现在用TimedOpen()替换对Open()所有调用并运行您的程序。 现在,对于您拥有的每个不同的连接字符串,控制台(输出)窗口将打开一个长时间运行的窗口,并打开一堆非常快的窗口。

如果要标记它们,可以将new StackTrace(true).GetFrame(1) +到对WriteLine的调用中。

物理连接和逻辑连接之间存在区别。 DbConnection 是一种逻辑连接,它使用底层物理连接到 Oracle。 关闭/打开 DbConnection 不会影响您的性能,但会使您的代码干净和稳定 - 在这种情况下连接泄漏是不可能的。

此外,您应该记住数据库服务器上并行连接存在限制的情况 - 考虑到有必要使您的连接非常短。

连接池将您从连接状态检查中解放出来 - 只需打开、使用并立即关闭它们。

通常你应该为每个事务保持一个连接(没有并行计算)

例如,当用户执行收费操作时,您的应用程序需要先找到用户的余额并更新它,他们应该使用相同的连接。

即使ado.net有自己的连接池,调度连接成本也很低,但是重用连接是更好的选择。

为什么不在应用中只保持一个连接

因为当你执行一些查询或命令时连接被阻塞,所以这意味着你的应用程序同时只做一个数据库操作,它的性能有多差。

另一个问题是,即使您的用户只是打开它但没有操作,您的应用程序也将始终有连接。如果有很多用户打开您的应用程序,数据库服务器将很快消耗其所有连接源,而您的用户还没有这样做任何事物。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM