Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# &引用;“打开/关闭”;SqlConnection还是保持打开状态?_C#_Sqlconnection - Fatal编程技术网

C# &引用;“打开/关闭”;SqlConnection还是保持打开状态?

C# &引用;“打开/关闭”;SqlConnection还是保持打开状态?,c#,sqlconnection,C#,Sqlconnection,我用静态方法在简单的静态类中实现了我的业务逻辑。调用这些方法时,每个方法都会打开/关闭SQL连接: public static void DoSomething() { using (SqlConnection connection = new SqlConnection("...")) { connection.Open(); // ... connection.Close(); } } 但我认为

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

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

        // ...

        connection.Close();
    }
}
但我认为避免打开和关闭连接可以节省性能。很久以前,我用OleDbConnection类做了一些测试(不确定是否使用SqlConnection),它确实有助于这样工作(据我记忆所及):

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


另外,这是一个ASP.NET应用程序-连接仅在web请求期间存在。不是win应用程序或服务。

始终在使用完连接后立即关闭连接,以便它们可以返回到池中,并可供其他呼叫者使用。连接池得到了很好的优化,因此这样做没有明显的惩罚。该建议基本上与交易的建议相同——在完成交易时保持简短

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


然而,您在这里手工操作,因此您可能需要研究为您管理连接的工具,如数据集、Linq到SQL、实体框架或NHibernate。

坚持选项a

连接池是您的朋友。

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


连接池按tin上的说明执行。想想应用程序扩展时会发生什么,手动管理连接打开/关闭状态有多困难。连接池在自动处理这方面做得很好。如果您担心性能,请考虑某种内存缓存机制,这样就不会阻塞任何内容。

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

此外,您还应该记住db服务器上的并行连接存在限制的情况——考虑到这一点,有必要使连接非常短


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

免责声明:我知道这很旧,但我找到了一种简单的方法来证明这一点,所以我投入了我的两分钱

如果您无法相信池的速度会更快,请尝试一下:

在某处添加以下内容:

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()
并运行程序。现在,对于您拥有的每个不同的连接字符串,console(output)窗口将有一个长时间运行的打开窗口,以及一组非常快速的打开窗口

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

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

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

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

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

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


还有一个问题是,即使您的用户刚刚打开应用程序但未进行任何操作,您的应用程序仍将始终具有连接。如果有许多用户打开您的应用程序,db server很快就会占用其所有连接源,而您的用户却什么都没有做。

您不应该在每个方法调用中正常打开和关闭连接,每个页面请求只打开和关闭一次连接。这是我至少学到的;)打开和关闭要花费时间。@David Martenson-调用SqlConnection.Open时,连接实际上并没有打开和关闭。当连接字符串与以前使用的连接字符串匹配时,ASP.NET将从池中回收活动连接。这其中涉及的开销是无关紧要的,此外,尝试“自己动手”意味着您必须承担所有管理任务,以确保连接在每次后续使用中仍处于活动状态,这增加了复杂性和开销。对于连接池,最好的做法是在每次使用时打开和关闭它。恕我直言,答案“总是关闭连接”并不适合这个问题。。。我确实关闭了它们。问题是-什么时候。@David Martenson“每页一次”过于简单化了。如果有多个数据库命令要一个接一个地执行,则可以在执行时保持连接打开,这是正确的。如果您关闭并重新打开连接,将产生较小的开销-连接将进入池中,并在片刻后从池中恢复。@David Martenson,但永远不要保持空闲连接。如果您正在等待用户的操作或其他操作,请将其关闭。如果有疑问,请关闭它。您尽可能晚地打开,希望其他人已完成连接并将其共享。然后返回优惠-尽可能早地关闭。只是一个建议:使用
DbConnection.StateChange
事件监视连接状态的更改
using System.Diagnostics;
public static class TestExtensions
{
    public static void TimedOpen(this SqlConnection conn)
    {
        Stopwatch sw = Stopwatch.StartNew();
        conn.Open();
        Console.WriteLine(sw.Elapsed);
    }
}