2011-05-18 93 views
2

我有以下方法:關閉SQL連接,但打開的連接不斷遞增

public DataSet GetDataSet(string sp, params SqlParameter[] parameters) { 
DataSet ds = new DataSet(); 

using (SqlConnection conn = new SqlConnection(
     ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString 
    )) { 
    using (SqlCommand cmd = new SqlCommand()) { 
     cmd.Connection = conn; 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.CommandText = sp; 

     if (parameters != null) { 
      foreach (SqlParameter parm in parameters) { 
       cmd.Parameters.Add(parm); 
      } 
     } 

     if (conn.State == ConnectionState.Closed) { 
      conn.Open(); 
     } 

     using (SqlDataAdapter da = new SqlDataAdapter(cmd)) { 
      da.Fill(ds); 
     } 
    } 
} 

return ds; } 

我注意到,調用此方法多次(約50倍)時創建多個連接。 我已經在SQL執行這個查詢選中此:

SELECT DB_NAME(dbid) as 'DbNAme', COUNT(dbid) as 'Connections' from master.dbo.sysprocesses with (nolock) WHERE dbid > 0 GROUP BY dbid 

連接的數量保持調用上述方法時遞增。它不應該一次又一次地使用相同的連接(連接池),而不是創建新的連接?

回答

3

這個link很好地解釋了連接池。如果你想了解整個事情,你應該閱讀這一個,這是非常好的。

Connection pooling reduces the number of times that new connections must be opened. The pooler maintains ownership of the physical connection. It manages connections by keeping alive a set of active connections for each given connection configuration. Whenever a user calls Open on a connection, the pooler looks for an available connection in the pool. If a pooled connection is available, it returns it to the caller instead of opening a new connection. When the application calls Close on the connection, the pooler returns it to the pooled set of active connections instead of closing it. Once the connection is returned to the pool, it is ready to be reused on the next Open call.

0

嘗試在填充數據集後關閉連接。使用statment發佈對象,但它不關閉連接。

+2

這是部分錯誤。使用語句將調用連接上的處置,並等同於Close方法。底層連接是否關閉取決於池:http://msdn.microsoft.com/en-us/library/sd2728ad(v=VS.100).aspx – 2011-05-18 10:28:38

+2

從MSDN:「如果SqlConnection超出範圍,它不會被關閉,因此,你必須通過調用Close或Dispose來明確地關閉連接,Close和Dispose在功能上是等價的「 – 2011-05-18 10:33:10

+0

你沒事。抱歉,不正確的答案! – Reniuz 2011-05-18 11:03:16

4

試圖增加最大池大小在你的連接字符串在web.config中像這樣

<add name="ConString" connectionString="SERVER=localhost;DATABASE=databasename;UID=username;PWD=password;Pooling=true;Max Pool Size=100;"/> 

或任何你定義it.it解決了這個問題,但暫時永久解決方案搜索你的代碼可能是你沒關連接

希望它會幫助你

+0

如果我不使用上述方法,則問題不存在。在某些時候,我有超過100個連接打開,然後我收到以下錯誤:_「Timeout expired。在從池中獲取連接之前超時的時間已經發生,這可能是因爲所有池連接都在使用中,並且max pool大小達到了。「_ – thomasvdb 2011-05-18 11:24:53

+0

@thomasvb你也可以在命令中設置timout peiord,就像下面的cmd.commandtimeout = 100或任何時間以毫秒爲單位 – Devjosh 2011-05-18 11:50:41

+0

@Devjosh我會嘗試它,但這不是我想的正常行爲? – thomasvdb 2011-05-18 12:47:08

3

連接池並不意味着它會重複使用的連接。由於建立SQL連接的開銷很大,因此連接池將保持固定的最大連接數打開,並且當您在連接上調用.Close()時,它將簡單地返回到池,然後當調用Open()時能夠將其傳遞到新連接在一個新的實例。

該機制內置於SqlConnection類中,這就是爲什麼它對用戶透明的原因;簡而言之:只要您正確地連接(正如您所做的那樣),您不應該擔心打開的連接數量。

+0

在某些時候,我得到了超過100個連接,導致此錯誤:超時過期。在從池中獲取連接之前已超時。發生這種情況的原因可能是因爲所有連接池都在使用中,並且達到最大池大小。 – thomasvdb 2011-05-18 11:03:12