【问题标题】:What happens to an unclosed database connection?未关闭的数据库连接会发生什么?
【发布时间】:2009-06-19 14:42:46
【问题描述】:

今天早些时候,我在我们的一个项目中发现了一个错误 - 与永远不会关闭的数据库有一个连接,我的意思是永远不会调用 Close() 方法。但是,当我关闭应用程序时,连接已关闭(多次在 sql management studio 中检查)。为什么?

【问题讨论】:

    标签: .net database-connection


    【解决方案1】:

    应用程序退出时连接将关闭。阅读SqlConnection's Finalize。来自 MSDN 的 Object.Finalize 文档:

    “在应用程序域关闭期间,会自动对未免于终结的对象调用终结,即使是那些仍可访问的对象。”

    【讨论】:

    • "如果 SqlConnection 超出范围,它不会被关闭。因此,您必须通过调用 Close 或 Dispose 显式关闭连接。" -这个也是msdn的,不调用Close()是不是连接可能不会关闭?
    • 您基本上可以执行 Close、Dispose 或 using() {},无论如何您都应该这样做。当应用程序关闭时,连接也将关闭,原因我在回答中已说明。
    • 此外,如果 GC 在任何时候决定完成连接,那么它们也将被关闭。
    【解决方案2】:

    这里要记住的另一件事是,在 .Net 中,您可以将连接包装在 using 块中,这将关闭并为您处理连接。因此,如果您在那里有 using 块,那么缺少明确的 Close() 并不是一件坏事......

    // this using block will auto close & dispose your connection...
    using (var conn = new SqlConnection(...))
    {
        conn.Open();
        // database code here with no explicit close
    
    }
    

    这与 try/finally 块在 finally 中带有 conn.close 的功能等价。许多开发者忽略了 using 块 - 确保在这种情况下你没有做同样的事情。

    如果您确实重写代码以关闭连接 - 最好在所有数据库对象(连接、命令、读取器)周围使用使用块,以确保它们在超出范围时关闭和处置使用块。我肯定会建议将它们写入您的代码,而不仅仅是 conn.Close() 在需要的地方。

    【讨论】:

    • 是的,我就是这样做的。如果您使用 FXCop,您将永远不会遇到问题,因为它会警告您不要调用 Dispose。
    • 没有使用块,我知道。
    • 这不是问题的答案
    • @agnieszka - 你会惊讶于有多少人忽略了这一点,并在 using 块中将缺少 Close 称为 bug。我只是指出了许多人忽略的东西。当您对我投反对票时,我也在研究您其他问题的答案,所以非常感谢...
    【解决方案3】:

    SQL 连接的创建成本很高,ADO.NET 使用一种称为连接池的技术,允许重用它们。

    引用MSDN:

    强烈建议您 当你总是关闭连接 已完成使用它,以便它将 返回到连接池和 被重复使用。

    如果最大池大小已 已到达并且没有可用的连接 可用,请求已排队。这 pooler 然后尝试回收任何 连接直到超时 达到(默认为 15 秒)。 如果 pooler 不能满足 在连接时间之前请求 out,抛出异常。

    【讨论】:

    • 事实上,由于连接池的原因,SQL 连接永远不会真正关闭 - 它只是返回到池中以便在您调用 Close 时重用。当应用程序域被销毁时,即您退出应用程序时,它将关闭。因此,如果您从不调用 Close 连接将不会被重用,并且一旦池用尽,您将收到异常。
    • @darin- 从不真正关闭是不正确的。在一定程度的不活动后,连接将被关闭,但这只是吹毛求疵。
    • @RichardOD,我不会说这是吹毛求疵。我其实不知道这个事实。非常感谢您的精确度。
    【解决方案4】:

    当您以常规方式退出应用程序时,我希望终结器能够运行。如果连接仍然打开,他们将关闭连接。 只是不要依赖于此:这些终结器可能需要一段时间才能在您的应用程序的正常操作中运行,因此您将保持打开太多连接。

    当应用程序崩溃时,终结器可能不会运行,使连接在应用程序生命周期后保持打开状态。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-23
      • 2010-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多