2010-02-09 34 views
7

假设我有一个ASP.NET页面。在页面加载事件处理程序中,我打开数据库连接并进行一些处理。但是处理完成后,我不通过调用连接对象的CLOSE方法来明确地关闭连接。如果我在ASP.NET网页中打开数据库连接,会发生什么情况

现在,当服务器端的页面处理完成后,GC将把所有的变量放置在我的页面中,并且也放置在连接对象中。但是当它被丢弃时,之前打开的连接是否会自动关闭?我的意思是,当GC配置连接对象时,它是否会自动关闭与数据库服务器建立的连接;或者只是简单地处理连接对象,并且数据库中的连接保持打开状态,直到数据库发生连接超时,然后数据库服务器自行关闭连接?

+0

当你说“变量”是指你的类的成员字段,还是你的意思是局部变量。 – 2010-02-09 05:48:10

+0

我的意思是局部变量,就像在一个类的方法中声明的一些变量一样.. – 2010-02-09 06:16:17

+0

危险!!!!!!!!! – jaywon 2010-02-09 07:50:40

回答

6

MSDN documentation是这个相当清楚的:

如果SqlConnection的超出 范围,它不会被关闭。因此, 您必须通过调用Close或 Dispose来明确关闭 连接。 Close and Dispose在功能上等同于 。

使用using块自动处理它,或明确地.Close()它。 using块是首选。

通过离开连接打开您的应用程序最终可能会在尝试新请求时耗尽连接,从而导致错误。我在一个正在调试的应用程序中遇到过这样的问题。最初的开发者未能在几页上明确地关闭连接,并且流量足够高,以至于用户开始出现错误。我用using块封装了违规连接,问题消失了。

+0

有趣的是,在SqlConnection类的Close和Dispose之间存在一些差异。除了在调用Close之后能够重新打开连接的明显区别之外,SqlConnection类在调用关闭期间不会从终结器队列中取消注册(通过调用GC.SuppressFinalize(this))。这会增加GC上的压力。 IMO实际上是SqlConnection类中的一个错误。 – Steven 2010-02-09 10:05:33

2

你应该使用using块,那么你就不必问这样一个问题:

using (var conn = new SqlConnection(connectionString)) 
{ 
    using (var cmd = new SqlCommand(commandText, conn)) 
    { 
     using (var reader = cmd.ExecuteReader()) 
     { 
      while (reader.Read()) { /* ... */ } 
     } 
    } 
} 
+0

如果我使用using块,那么数据库中的连接将被gcc关闭? – 2010-02-09 05:45:46

+0

否。即使在块内引发异常,连接将在使用块的末尾处关闭。 – 2010-02-09 05:47:35

+1

实际上,与数据库的连接通常不会关闭,但它只是返回到连接池。但是,如果不正确地处理(或关闭)连接,则会耗尽池并最终导致连接池超时异常。 – Steven 2010-02-09 10:11:26

3

连接是保持开放。如果你有很多浏览量,并且有很多打开的连接,你可能会得到500错误。

3

直到之后(不是当)你的页面对象被定稿后,你的连接才会被关闭,这可能是一段时间。最大限度地利用可用连接的数量并开始获取错误是非常容易的。

1

除非通过GC选择,否则您的连接将不会关闭,并且如果您有许多访问者导致大量连接,那么这可能会很糟糕。另外,如果你尝试打开一个打开的连接,它会抛出错误,所以你必须检查一下是否使用block或者自己关闭连接。

相关问题