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

我将业务逻辑实现在具有静态方法的简单静态类中。每个方法在调用时打开/关闭 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) ?我在另一个堆栈溢出问题中读到,连接池为我节省了性能,我根本不需要麻烦..。

另外,这是一个 ASP.NET 应用程序——连接只存在于网络请求中,而不是一个双赢的应用程序或服务。

113913 次浏览

总是在连接完成后立即关闭它们,这样它们的底层数据库连接就可以回到池中,并可供其他调用者使用。连接池被很好地优化了,所以这样做没有明显的代价。这个建议基本上和处理事务的建议一样——当你处理完事务后,保持它们的简短和关闭。

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

然而,在这里您是手工操作的,所以您可能需要研究一些工具来为您管理连接,比如 DataSet、 Linq to SQL、 Entity Framework 或 NHibernate。

坚持选项 a

连接池是您的朋友。

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

连接池按照它在锡上所说的那样运行。想想当应用程序可伸缩时会发生什么,以及手动管理连接打开/关闭状态会有多难。连接池在自动处理这个问题方面做得很好。如果您担心性能问题,可以考虑使用某种内存缓存机制,这样就不会阻塞任何内存。

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

另外,您还应该记住数据库服务器上的并行连接受到限制的情况——考虑到这一点,有必要让您的连接非常短。

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

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

如果你不能相信池化真的会更快,那么试试这个:

在某处添加以下内容:

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的调用中。

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

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

即使 ado.net 有它的连接池,分派连接成本也非常低,但是重用连接是更好的选择。

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

因为在执行某个查询或命令时连接被阻塞, 这意味着您的应用程序同时只执行一个 db 操作, 它的表现有多么糟糕。

另一个问题是你的应用程序总是有一个连接,即使你的用户只是打开它,但没有操作。如果有很多用户打开你的应用程序,数据库服务器将很快耗尽其所有的连接源,而你的用户什么都没有做。