为什么不应该在finally块中关闭数据库连接?

4

重要更正: 我误读了文章! 评论是关于类的finalize方法而不是finally块的 :). 抱歉。

我刚刚读到一个文章,说你不应该在finally块中关闭或释放数据库连接,但是该文章没有解释为什么。 我似乎找不到明确的解释,说明为什么不这样做。

这是文章链接


1
你能链接回原始文章吗? - Gavin Miller
如果文章在网上可以找到的话,我认为你应该放上文章的链接。 - Jhonny D. Cano -Leftware-
听起来像是一篇虚假的文章... - womp
也许这篇文章(需要该链接!)正在推动使用using语句而不是try-finally?但仍然表明文章的作者不理解使用语句的作用。 - Richard
不要在终结器中放置关闭操作,因为您不知道何时会触发它。但是可以放在 finally 语句块中。请查看此 MSDN 文章。http://msdn.microsoft.com/zh-cn/library/system.object.finalize.aspx - Jim Scott
6个回答

13

如果你仔细观察,关闭连接的方式通常是在finally块中实现。你看的那篇文章可能建议在使用连接的代码周围加上一个 “using” 语句。

using (SqlConnection connection = new SqlConnection(connectionString))
{
    SqlCommand command = connection.CreateCommand();

    command.CommandText = "select * from someTable";

    // Execute the query here...put it in a datatable/dataset
}

'using'语句将确保在需要时立即处理Connection对象,而不是等待垃圾收集器进行处理。


1
...而using语句只是try-finally的一种语法快捷方式。 - Richard
1
这不仅仅是一个快捷方式。try-finally块在垃圾回收器起作用之前不会处理对象,而using语句将在块完成后立即处理。 - Justin Niessner
SqlConnection connection; 尝试 { connection = new SqlConnection(connectionString); connection.Open(); } 最后 { connection.Dispose(); } - Jim Scott

4

我不同意在finally块内不关闭或处理数据库连接。

如果有很多活动,让未处理的(甚至已处理的)异常保持打开状态可能会迅速导致数据库崩溃。

关闭数据库连接是使用finally语句的典型示例。当然,using语句是我首选的方法,这也许是原始作者的初衷。

主要编辑: 现在这样说就有道理了。你不希望把关闭数据库连接交给垃圾收集器。


3
没有原始文章,我无法代表作者发言。但是,根据您如何实现实例化和打开连接与try/catch/finally块的关系,您可能需要在调用close之前进行一些附加检查。例如,确保连接不为null且未关闭。

编辑:文章说不要在Finalize方法中处理连接对象,而不是不要在finally块中关闭它。实际上,在上面的段落中,它说在使用后应始终关闭连接,以便将其返回到连接池中。

“警告建议您在使用完Connection后始终关闭它,以便将连接返回到池中。这可以使用Connection对象的Close或Dispose方法来完成。未明确关闭的连接可能不会被添加或返回到池中。例如,已超出范围但未显式关闭的连接仅在达到最大池大小且连接仍然有效时才会返回到连接池中。

请注意,在类的Finalize方法中不要调用Connection、DataReader或任何其他托管对象的Close或Dispose。在终结器中,只释放直接拥有的非托管资源。如果您的类不拥有任何非托管资源,请勿在类定义中包含Finalize方法。有关更多信息,请参见“

http://msdn.microsoft.com/en-us/library/8xx3tyca(VS.71).aspx?ppud=4


2
一点点谷歌搜索就可以找到很多页面持有相反的 观点。使用“finally”块似乎是确保连接始终正确关闭的好方法,尽管正如其他人所说,我很想看看最初的文章是怎么说的。

2

从我在文章中看到的内容来看,它建议不要在类的Finalizer中调用Dispose或Close,而不是反对在finally块中这样做,这是完全不同的事情。


0

Close 方法将连接对象置于可重新打开的状态。而 Dispose 方法则将其置于不可重新打开的状态(如果当前已打开,则先关闭)。

如果您实例化一个连接,打开它,使用它,然后丢弃它(正常的使用模式),那么使用 using 块是最好、最简单的方法。

显然,如果您正在执行一些更复杂的操作,需要多次调用 OpenClose,那么释放它会对工作造成影响。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接