如果控制台程序终止,程序中使用的数据库连接是否仍然保持打开状态?

时间:2009-06-06 21:28:00

标签: database language-agnostic database-connection

在Java和C#中,它们都有类似System.terminate()的东西。如果我的程序有开放的数据库连接,数据库读取器和数据库命令变量,并且我在catch子句中终止我的程序,数据库资源是否仍然在使用?或者自从我的整个程序刚退出以来它们会被自动释放吗?

通常情况下,我应该如何处理这种情况以确保我总是释放数据库连接,无论是通过正常的程序终止还是意外的程序终止?有什么好的做法吗?

8 个答案:

答案 0 :(得分:6)

在流程终止后,所有相关资源(包括内存,句柄,连接等)都将被释放。

通常,在C#中,您将使用Dispose模式/ using语句来控制稀缺资源。

答案 1 :(得分:5)

除非您特别关闭连接,否则它们将保持打开状态,直到超时结束。

我几次在C#中发现了这个问题。最佳实践要求关闭/关闭您不再需要的资源。文件I / O流,数据库连接等

答案 2 :(得分:1)

在C#中,如果在被垃圾收集的对象中实现终结器,则由垃圾收集器完成隐式清理。可以在Dispose方法中完成对非托管资源(如数据库连接)的任何清理。

有关更多信息,请参阅此文章:

实施完成并处理以清理非托管资源
http://msdn.microsoft.com/en-us/library/b1yfkh5e(VS.71).aspx

答案 3 :(得分:1)

当进程终止时,操作系统应释放它已打开的所有文件描述符。文件描述符包括文件和套接字,通常用于覆盖数据库连接。

所有这些都告诉您,当您的客户端终止时,其关闭将被关闭。它没有告诉你服务器做了什么。根据其编写方式,服务器完全有可能继续保持其连接打开,期望来自客户端的消息永远不会到达,甚至尝试发送数据。这些可能最终会超时,但这可能不是很好的计划。 (应该是,对于一个体面的RDBMS,但它可能不是。)因此,根据您的RDBMS,您可能需要采取一些步骤告诉服务器您要关闭以告知它释放其资源。

答案 4 :(得分:1)

如果您正在使用SQL Server,可以查看sysprocesses或运行sp_who2。我在我的机器上对此进行了测试,并且连接已关闭,即:

Console.Write("Opening connection");
Console.ReadLine();
SqlConnection connection = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=SeniorMail;Integrated Security=SSPI;");
connection.Open();
SqlCommand command = new SqlCommand("SELECT count(*) from Account", connection);
Console.Write("Running sql");
Console.ReadLine();
int? count = command.ExecuteScalar() as int?;
Console.Write("Now I'll throw an exception");
Console.ReadLine();
int a = 0, b = 1, c = 0;

try
{
    c = b / a;
}
catch
{
    Environment.Exit(1);
}

我已经检查了sp_who2“现在我将抛出异常”,我可以看到应用程序退出后连接已消失。

答案 5 :(得分:0)

一般POSIX行为是,当程序终止时,所有文件句柄,网络连接等都将关闭。在这一点上,另一端是否做正确的事是一个悬而未决的问题,但如果你使用任何相当受欢迎的RDBMS,那就没关系了。

答案 6 :(得分:0)

在C#中,您通常会在使用它们后立即关闭连接,例如:

using(SqlConnection connection = ...)
{
   ... do something ...
} // connection disposed / closed here

但是通常您将使用连接池,所有这一切都会返回到池的连接。因此,您的进程仍将与数据库服务器建立活动连接。

如果您干净地关闭,毫无疑问将清除连接池,并且将关闭与数据库的实际连接(您可以通过查看数据库服务器上的打开连接来验证这一点。)

但是有些情况(例如调用Environment.FailFast)应用程序可能会崩溃而不关闭连接 - 在这种情况下,它们最终会超时并被数据库服务器关闭。

答案 7 :(得分:-1)

应该在下一个GC上清除它,但准确地说,在C#中,您可以关闭结构化异常处理的finally块上的连接。

try {
  // open DB connection
} catch (Exception ex) {
  // deal with exception
} finally {
  // close and dispose connection
}