未封闭的数据库连接会发生什么?

时间:2021-07-08 15:19:34

Earlier today I've found a bug in one of our projects - there is a conenction with database that is never closed, i mean the Close() method is never called. However, when I close the application, the connection is closed (checked in sql management studio many times). Why?

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

4 个解决方案

#1


The connection will close when the application exits. Read up on SqlConnection's Finalize. From MSDN's documentation for Object.Finalize:

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

"During shutdown of an application domain, Finalize is automatically called on objects that are not exempt from finalization, even those that are still accessible."

“在关闭应用程序域期间,会自动调用Finalize,这些对象不会被终结,即使是那些仍然可以访问的对象。”

#2


Another thing to keep in mind here is that in .Net, you can wrap your connections in a using block, and that will close and dispose your connections for you. So the lack of an explicit Close() isn't a bad thing if you've got your using blocks there...

另外要记住的是,在.Net中,您可以将连接包装在一个使用块中,这将关闭并为您配置连接。所以如果你在那里使用了块,那么缺少一个明确的Close()并不是一件坏事......

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

}

that is the functional equivalent of a try/finally block with a conn.close in the finally. Many devs overlook the using blocks - make sure you're not doing the same in this case.

这是在finally中使用conn.close的try / finally块的功能等价物。许多开发人员忽略了使用块 - 确保在这种情况下你不会做同样的事情。

If you do rewrite your code to close your connections - it's good practice to use Using blocks around all of your database objects (connection, command, reader) to make sure that they are closing and disposing when they fall out of scope of the using block. I'd definitely suggest writing those into your code instead of just conn.Close() where needed.

如果您重写代码以关闭连接 - 最好在所有数据库对象(连接,命令,阅读器)周围使用块来确保它们在不在使用块的范围之外时关闭和处理。我肯定建议在你的代码中编写它们而不是只需要conn.Close()。

#3


SQL connections are expensive to create and ADO.NET uses a technique called connection pooling which allows to reuse them.

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

Quote from MSDN:

从MSDN引用:

It is strongly recommended that you always close the connection when you are finished using it so that it will be returned to the connection pool and be reused.

强烈建议您在使用完毕后始终关闭连接,以便将其返回到连接池并重复使用。

If the maximum pool size has been reached and no usable connection is available, the request is queued. The pooler then tries to reclaim any connections until the time-out is reached (the default is 15 seconds). If the pooler cannot satisfy the request before the connection times out, an exception is thrown.

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

#4


When you exit the application in a regular fashion, I expect the finalizers to run. They will close the connection if it is still open. Just don't depend on this: it might take a while before those finalizers are run in normal operation of your application, so you will be keeping too many connections open.

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

When the application crashes, maybe the finalizer will not run, leaving the connection open past the lifetime of the application.

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

#1


The connection will close when the application exits. Read up on SqlConnection's Finalize. From MSDN's documentation for Object.Finalize:

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

"During shutdown of an application domain, Finalize is automatically called on objects that are not exempt from finalization, even those that are still accessible."

“在关闭应用程序域期间,会自动调用Finalize,这些对象不会被终结,即使是那些仍然可以访问的对象。”

#2


Another thing to keep in mind here is that in .Net, you can wrap your connections in a using block, and that will close and dispose your connections for you. So the lack of an explicit Close() isn't a bad thing if you've got your using blocks there...

另外要记住的是,在.Net中,您可以将连接包装在一个使用块中,这将关闭并为您配置连接。所以如果你在那里使用了块,那么缺少一个明确的Close()并不是一件坏事......

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

}

that is the functional equivalent of a try/finally block with a conn.close in the finally. Many devs overlook the using blocks - make sure you're not doing the same in this case.

这是在finally中使用conn.close的try / finally块的功能等价物。许多开发人员忽略了使用块 - 确保在这种情况下你不会做同样的事情。

If you do rewrite your code to close your connections - it's good practice to use Using blocks around all of your database objects (connection, command, reader) to make sure that they are closing and disposing when they fall out of scope of the using block. I'd definitely suggest writing those into your code instead of just conn.Close() where needed.

如果您重写代码以关闭连接 - 最好在所有数据库对象(连接,命令,阅读器)周围使用块来确保它们在不在使用块的范围之外时关闭和处理。我肯定建议在你的代码中编写它们而不是只需要conn.Close()。

#3


SQL connections are expensive to create and ADO.NET uses a technique called connection pooling which allows to reuse them.

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

Quote from MSDN:

从MSDN引用:

It is strongly recommended that you always close the connection when you are finished using it so that it will be returned to the connection pool and be reused.

强烈建议您在使用完毕后始终关闭连接,以便将其返回到连接池并重复使用。

If the maximum pool size has been reached and no usable connection is available, the request is queued. The pooler then tries to reclaim any connections until the time-out is reached (the default is 15 seconds). If the pooler cannot satisfy the request before the connection times out, an exception is thrown.

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

#4


When you exit the application in a regular fashion, I expect the finalizers to run. They will close the connection if it is still open. Just don't depend on this: it might take a while before those finalizers are run in normal operation of your application, so you will be keeping too many connections open.

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

When the application crashes, maybe the finalizer will not run, leaving the connection open past the lifetime of the application.

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