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

时间:2010-12-14 12:59:49

标签: c# sqlconnection

我的业务逻辑是用静态方法在简单的静态类中实现的。这些方法中的每一个在调用时打开/关闭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或服务。

6 个答案:

答案 0 :(得分:77)

每次使用方法(a)。当你开始扩展应用程序时,处理状态的逻辑将成为一个真正的痛苦,如果你不这样做。

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

答案 1 :(得分:73)

坚持选项

连接池是你的朋友。

答案 2 :(得分:28)

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

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

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

答案 3 :(得分: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的通话中。

答案 4 :(得分:7)

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

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

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

答案 5 :(得分:0)

  

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

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

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

  

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

由于执行某些查询或命令时连接正在阻塞, 这意味着您的应用程序只能同时执行一个数据库操作, 性能多么差。

另一个问题是,即使您的用户只是打开应用程序但没有任何操作,您的应用程序仍将始终具有连接。如果有很多用户打开您的应用程序,则db server将在您的用户很快花费所有连接资源什么也没做。