出错后不关闭数据库连接会有啥后果?

Posted

技术标签:

【中文标题】出错后不关闭数据库连接会有啥后果?【英文标题】:What are the consequences of not closing database connection after an error?出错后不关闭数据库连接会有什么后果? 【发布时间】:2008-09-27 19:04:37 【问题描述】:

我有一个令人头疼的应用程序。它是一个通过 Web 服务连接到 SQL Server 2005 的 .NET 应用程序。该程序的网格由易于超时的长时间运行的存储过程填充。在超时并抛出 SqlException 的情况下,没有执行关闭连接的处理。

这种情况的实际后果是什么?我认为框架或 SQL Server 可能会以一种或另一种方式处理它,但我不确定。

加法 该程序在早上总是运行良好,但使用一个小时左右后它基本上停止工作。问题不在于我不知道如何正确编码连接。我需要知道这些症状是否可能是由未关闭的连接引起的。更改生产代码是一件大事,我想知道这至少有可能成为问题。

结论 我设计这种失败发生在数百个同时连接上。我永远无法在应用程序环境中重现故障情况。将最佳实践答案标记为正确。谢谢大家。

【问题讨论】:

我认为标签应该是 sql-server 而不是问题显示的两个单独的标签 听起来您在生产环境中打开了连接池。启用池化后,即使您告诉它们关闭连接也不会关闭,因此您不关闭它们也没关系。 【参考方案1】:

由于 SqlConnection 在处理时关闭,我通常使用这种语法

using (SqlConnection conn = new SqlConnection())

  // SqlCode here 

【讨论】:

【参考方案2】:

有连接限制;如果您的应用程序经常崩溃并且没有自动关闭连接,则新的连接请求将被拒绝。

也就是说,如果连接没有关闭,连接会在一段时间后超时。

【讨论】:

【参考方案3】:

如果应用程序在一个小时左右后停止工作,那肯定是由于连接未关闭/处置造成的。

【讨论】:

【参考方案4】:

这就是为什么在使用 ADO.Net 时“using”关键字如此重要的原因

 using ( SqlConnection conn = new SqlConnection() )
 
     ...
 

这会强制使用 IDispose 接口对 ADO.Net 对象进行一种确定性垃圾回收。

大多数数据库代码为此使用大量嵌套的“使用”子句。

【讨论】:

IDispose 接口与垃圾回收无关。它强制非托管资源的确定性释放。 乔,你的说法不正确。 IDispose 与非托管资源没有任何关系。例如,查看codeproject.com/KB/mcpp/garbage_collection.aspx。【参考方案5】:

如果经常发生这种情况,您可能会用完可用的连接,您应该在执行命令的任何地方使用 finally 来关闭连接。

【讨论】:

【参考方案6】:

垃圾收集器最终会完成你打开的连接对象,但你不知道下次 GC 何时到来。在此之前,如果您有大量流量或者它是共享 sql 服务器,您的池中的连接可能会用完。

为什么不将它放在 try/catch 块的 finally 部分?

finally

   if (cn != null)
   
      cn.Dispose();
      cn = null;
   

这显然应该在web service方法中完成。

【讨论】:

你不需要“cn = null;” 我投票支持你是因为你是唯一一个提到池化的人。根据您是否使用连接池,连接的行为有很大不同。【参考方案7】:
try

    sqlCommandObject.Execute(); // this line will throw a timeout exception

finally

    sqlConnectionObject.Close(); // this will execute no matter what happens

【讨论】:

我认为 MS 和其他人的建议是使用 Dispose() 或正如 Pablo 指出的那样,使用块。 Dispose() 在连接对象上调用 Close(),并在必要时进行其他清理。 这个答案是“正确的”。 msdn.microsoft.com/en-us/library/… "Close 和 Dispose 在功能上是等效的。"

以上是关于出错后不关闭数据库连接会有啥后果?的主要内容,如果未能解决你的问题,请参考以下文章

java 中对输入输出流类型重复调用,只对最后一次调用进行关闭,之前的调用不关闭,会有啥后果?

Docker MySQL在超时后丢弃表:连接关闭后不允许操作

HikariCP - MYSQL 连接关闭后不允许操作。可能考虑使用更短的 maxLifetime 值

Elasticsearch Java High-Level REST Client 建立一堆 TCP 连接并且在索引数据后不关闭它们

MySQLNonTransientConnectionException:连接关闭后不允许操作。连接

为啥要使用 JSTL?当我们在 JSP 文件中使用带有连接字符串的数据库连接来获取从 servlet 发送的数据时会有啥危害[重复]