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

发布于 2024-10-07 12:13:48 字数 883 浏览 0 评论 0原文

我用静态方法在简单的静态类中实现了我的业务逻辑。这些方法中的每一个在调用时都会打开/关闭 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 问题中读到连接池为我节省了性能,我根本不必费心......

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

I have my business-logic implemented in simple static classes with static methods. Each of these methods opens/closes SQL connection when called:

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

        // ...

        connection.Close();
    }
}

But I think passing the connection object around and avoiding opening and closing a connection saves performance. I made some tests long time ago with OleDbConnection class (not sure about SqlConnection), and it definitely helped to work like this (as far as I remember):

//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();
    }
}

So the question is - should I choose the method (a) or method (b) ? I read in another stackoverflow question that connection pooling saved performance for me, I don't have to bother at all...

PS. It's an ASP.NET app - connections exist only during a web-request. Not a win-app or service.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

喜你已久 2024-10-14 12:13:48

坚持选项a

连接池是你的朋友。

Stick to option a.

The connection pooling is your friend.

诺曦 2024-10-14 12:13:48

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

连接池正如它所说的那样。想想当应用程序扩展时会发生什么,以及手动管理连接打开/关闭状态有多困难。连接池可以很好地自动处理这个问题。如果您担心性能,请考虑某种内存缓存机制,这样就不会阻塞任何内容。

Use Method (a), every time. When you start scaling your application, the logic that deals with the state will become a real pain if you do not.

Connection pooling does what it says on the tin. Just think of what happens when the application scales, and how hard would it be to manually manage the connection open/close state. The connection pool does a fine job of automatically handling this. If you're worried about performance think about some sort of memory cache mechanism so that nothing gets blocked.

再见回来 2024-10-14 12:13:48

使用完连接后,请务必立即关闭连接,以便它们的底层数据库连接可以返回到池中并可供其他调用者使用。连接池已经得到了很好的优化,因此这样做不会造成明显的损失。该建议与交易基本相同 - 保持简短并在完成后结束。

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

然而,您在这里手动执行操作,因此您可能需要研究为您管理连接的工具,例如 DataSets、Linq to SQL、Entity Framework 或 NHibernate。

Always close connections as soon as you are done with them, so they underlying database connection can go back into the pool and be available for other callers. Connection pooling is pretty well optimised, so there's no noticeable penalty for doing so. The advice is basically the same as for transactions - keep them short and close when you're done.

It gets more complicated if you're running into MSDTC issues by using a single transaction around code that uses multiple connections, in which case you actually do have to share the connection object and only close it once the transaction is done with.

However you're doing things by hand here, so you might want to investigate tools that manage connections for you, like DataSets, Linq to SQL, Entity Framework or NHibernate.

冰雪梦之恋 2024-10-14 12:13:48

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

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

在某处添加以下内容:

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

Disclaimer: I know this is old, but I found an easy way to demonstrate this fact, so I'm putting in my two cents worth.

If you're having trouble believing that the pooling is really going to be faster, then give this a try:

Add the following somewhere:

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

Now replace all calls to Open() with TimedOpen() and run your program. Now, for each distinct connection string you have, the console (output) window will have a single long running open, and a bunch of very fast opens.

If you want to label them you can add new StackTrace(true).GetFrame(1) + to the call to WriteLine.

¢蛋碎的人ぎ生 2024-10-14 12:13:48

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

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

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

There are distinctions between physical and logical connections. DbConnection is a kind of logical connection and it uses underlying physical connection to Oracle. Closing/opening DbConnection doesn't affect your performance, but makes your code clean and stable - connection leaks are impossible in this case.

Also you should remember about cases when there are limitations for parallel connections on db server - taking that into account it is necessary to make your connections very short.

Connection pool frees you from connection state checking - just open, use and immediately close them.

伴我心暖 2024-10-14 12:13:48

通常情况下,您应该为每个事务保留一个连接(无并行计算)

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

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

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

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

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

Normally you should keep one connect for each transaction(no parallel computes)

e.g when user execute charge action, your application need find user's balance first and update it, they should use same connection.

Even if ado.net has its connection pool, dispatching connection cost is very low, but reuse connection is more better choice.

Why not keep only one connection in application

Because the connection is blocking when you execute some query or command,
so that means your application is only doing one db operation at sametime,
how poor performance it is.

One more issue is that your application will always have a connection even though your user is just open it but no operations.If there are many user open your application, db server will cost all of its connection source in soon while your users have not did anything.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文