【问题标题】:Should I open and close db for each query?我应该为每个查询打开和关闭数据库吗?
【发布时间】:2011-03-14 20:40:40
【问题描述】:

我正在使用带有 C# 的老式 ADO.net,因此有很多此类代码。每个查询创建一个函数并每次打开和关闭数据库,还是使用相同的连接对象运行多个查询更好?以下只是一个查询,仅供参考。

 using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DBConnectMain"].ConnectionString))
    {
        // Add user to database, so they can't vote multiple times
        string sql = " insert into PollRespondents (PollId, MemberId) values (@PollId, @MemberId)";

        SqlCommand sqlCmd = new SqlCommand(sql, connection);

        sqlCmd.Parameters.Add("@PollId", SqlDbType.Int);
        sqlCmd.Parameters["@PollId"].Value = PollId;

        sqlCmd.Parameters.Add("@MemberId", SqlDbType.Int);
        sqlCmd.Parameters["@MemberId"].Value = Session["MemberId"];

        try
        {
            connection.Open();
            Int32 rowsAffected = (int)sqlCmd.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            //Console.WriteLine(ex.Message);
        }
    }

【问题讨论】:

  • 这是否适用于多个连续查询(例如 500 次插入)?还是定期查询?

标签: c# ado.net


【解决方案1】:

嗯,你可以测量;但只要您是using 连接(即使您遇到异常,它们也会被释放),并且启用了池(对于 SQL 服务器,默认情况下启用)它并不重要;关闭(或处置)只是将 底层 连接返回到池。两种方法都有效。对不起,这没有多大帮助;p

当你做其他冗长的非数据库工作时,不要保持打开的连接。关闭它并重新打开它;您实际上可能会得到相同的底层连接,但其他人(另一个线程)可能在您没有使用它时使用了它。

【讨论】:

    【解决方案2】:

    对于大多数情况,打开和关闭每个查询的连接是可行的方法(正如 Chris Lively 指出的那样)。但是,在某些情况下,您会遇到此解决方案的性能瓶颈。

    例如,当处理依赖于先前结果的大量相对快速执行的查询时,我可能建议在单个连接中执行多个查询。在对数据进行批处理或为报告目的进行数据按摩时,您可能会遇到这种情况。

    请务必使用“使用”包装器来避免内存泄漏,无论您遵循哪种模式。

    【讨论】:

    • “使用‘使用’包装器”是什么意思?
    • @TrackABill.com using (SqlConnection connection = new SqlConnection(connectionString)) { //Something }
    【解决方案3】:

    如果方法的结构使得单个命令在单个方法中执行,那么是:为每个命令实例化并释放连接。

    如果方法的结构使得您在同一代码块中执行多个命令,则外部块需要是连接的 using 子句。

    ADO 在连接池方面非常出色,因此命令对象的实例化和处置将非常快,并且不会真正影响性能。

    例如,我们有几个页面将执行更新到 50 个查询以组成页面。因为有分支代码来确定要运行的查询,所以我们将每个查询都用自己的using (connection...) 子句包装。

    我们曾经将它们撕掉并抓取一个连接对象并将其传递给各个方法。这使性能改进为零,同时使代码变得复杂,所有异常子句在每个地方都确保连接在最后得到正确处理。在测试结束时,我们将代码回滚到之前的样子。清楚地知道发生了什么以及何时使用连接。

    【讨论】:

      【解决方案4】:

      嗯,一如既往,这取决于。如果在同一个方法调用中要进行 5 次数据库调用,则可能应该使用单个连接。

      但是,从可扩展性的角度来看,通常不建议在没有发生任何事情的情况下保持连接。

      【讨论】:

        【解决方案5】:

        ADO.NET 现在是老派了?哇,你让我觉得自己老了。对我来说,在 Windows 3.1 上使用 Borland C++ 的 Rogue Wave ODBC 是老派。

        要回答这个问题,您通常需要了解数据驱动程序的工作原理。了解连接池等概念,并学习分析与连接/断开连接和执行查询相关的交易成本。然后将这些知识应用到你的情况中。

        【讨论】:

          猜你喜欢
          • 2020-12-31
          • 1970-01-01
          • 1970-01-01
          • 2013-02-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-15
          相关资源
          最近更新 更多