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

问题描述 投票:101回答:6

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

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

        // ...

        connection.Close();
    }
}

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

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

    // ....

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

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

PS。它是一个ASP.NET应用程序 - 仅在Web请求期间存在连接。不是win-app或服务。

c# sqlconnection
6个回答
74
投票

坚持选择a。

连接池是你的朋友。


77
投票

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

连接池完成它在锡上所说的内容。只需考虑应用程序扩展时会发生什么,以及手动管理连接打开/关闭状态的难度。连接池可以很好地自动处理它。如果你担心性能会考虑某种内存缓存机制,以免被阻止。


28
投票

完成后立即关闭连接,因此它们的基础数据库连接可以返回池中,并可供其他呼叫者使用。连接池已经过很好的优化,因此没有明显的惩罚。建议基本上与交易相同 - 保持简短并在完成后关闭。

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

但是你在这里手工做事,所以你可能想要研究管理连接的工具,比如DataSet,Linq to SQL,Entity Framework或NHibernate。


12
投票

免责声明:我知道这已经过时了,但我找到了一个简单的方法来证明这个事实,所以我要投入两分钱。

如果你很难相信汇集真的会更快,那么试试吧:

在某处添加以下内容:

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

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

如果你想标记它们,你可以添加new StackTrace(true).GetFrame(1) +来调用WriteLine


7
投票

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

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

连接池使您免于连接状态检查 - 只需打开,使用并立即关闭它们。


0
投票

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

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

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

为什么不在应用程序中只保留一个连接

因为在执行某些查询或命令时连接是阻塞的,所以这意味着您的应用程序只在同一时间执行一个db操作,它的性能有多差。

还有一个问题是你的应用程序总是会有一个连接,即使你的用户只是打开它但没有操作。如果有很多用户打开你的应用程序,db服务器将很快耗尽所有的连接源,而你的用户还没有任何东西。

© www.soinside.com 2019 - 2024. All rights reserved.