2011-07-06 64 views
10

我在使用.NET編寫的代碼中遇到問題。如何在我的連接池中找到正在使用的連接

的問題是,什麼地方我有一些狡猾的數據庫代碼,意味着一段時間後,我收到以下錯誤:

Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.

我知道,那是因爲我的地方沒有設置之一的我數據採集​​器或類似的東西,這意味着它仍然有連接打開,所以它沒有返回到池中。儘管我的代碼中發生了這種情況,但我遇到了一些問題。

所以我的問題:

有什麼辦法來查詢連接池,找出其使用的連接都在做。我只是在尋找一種方法來查找正在運行的查詢,以便我找到有問題的代碼。

對於它的價值,我沒有權限在有問題的數據庫上運行活動監視器來找出這種方式。

+0

您使用的是哪個版本的Framework? –

+0

@Conrad:2.0版 – Chris

回答

12

Is there any way to query the connection pool to find out what its in use connections are doing.

不是。連接池是你的應用程序維護的東西(實際上是一個List<DbConnectionInternal>)如果你真的想通過反射或如果你正在調試,通過本地或觀察窗口(見下文),但你可以從那裏或者哪個對象應該調用Connection.Close(或者Dispose),不會從那個連接上發生什麼。這樣不利於

enter image description here

如果幸運的話,你可以在你的超時時刻執行sp_who或sp_who2當你用完池連接時,但它很有可能是大部分的結果會看起來像這樣。

SPID Staus Login Hostname Blkby DBname Command   .... 
---- ------- ----- --------- ----- ------ ---------------- 
79 sleeping uName WebServer .  YourDb AWAITING COMMAND ..... 
80 sleeping uName WebServer .  YourDb AWAITING COMMAND ..... 
81 sleeping uName WebServer .  YourDb AWAITING COMMAND ..... 
82 sleeping uName WebServer .  YourDb AWAITING COMMAND ..... 

這意味着確實您的應用程序已經打開了很多連接,並沒有關閉它們,甚至沒有對它們做任何事情。

解決這個問題的最好方法是在你的應用程序中使用ADO.NET Performance Counters,並密切關注NumberOfReclaimedConnections並進行全面的代碼審查。

如果您真的絕望,可以在遇到此問題時清除池。

using (SqlConnection cnn = new SqlConnection("YourCnnString")) 
{ 

    try 
    { 
      cnn.Open(); 
    } 
    catch (InvalidOperationException) 
    { 
      SqlConnection.ClearPool(cnn); 
    } 
    cnn.Open(); 

} 

然而,我警告你不要這樣,因爲它有窒息您的數據庫服務器的潛力,因爲它可以讓你的應用程序打開儘可能多的連接,服務器將允許它只是耗盡資源之前。

+0

感謝康拉德,這似乎是一個相當全面的答案,並說出我的懷疑。最後,我決定對於數據庫訪問的寫入方式感到不滿,最終只是徹底翻修了它,這對未來很有用,特別是關於如何在監視窗口中查找連接池的指針。:) – Chris

2

您是否嘗試過加載SSMS並在有問題的數據庫上運行sp_who2

USE [SomeDatabase] 
EXEC sp_who2 

這應該會告訴你什麼時候發生了什麼。

+0

剛剛嘗試過(sp_who2如果你想改正你的錯字),但它只返回我當前的連接。我試圖改變我的連接使用相同的連接設置作爲問題的代碼,但仍然只顯示我的一行似乎是我目前的連接。我認爲這是相同的權限問題,阻止我運行活動監視器。 :(謝謝你的建議,儘管 – Chris