2010-02-27 37 views
1

我遇到了一個令人沮喪的問題,我原本以爲是連接泄漏,但似乎並非如此。該規範是這樣的:此應用程序的數據訪問使用Microsoft的企業庫(v4)。所有的數據訪問調用被包裝在使用語句,如ASP.NET SqlConnection超時問題

using (DbCommand dbCommand = db.GetStoredProcCommand("sproc")) 
{ 
    db.AddInParameter(dbCommand, "MaxReturn", DbType.Int32, MaxReturn); 
    ...more code 
} 

現在這個應用程序的索引,使8個調用數據庫加載的一切,我可以通過刷新該指數約15倍使應用程序癱瘓。看來,當數據庫達到113個連接時,我收到這個錯誤。這是什麼讓這個奇怪的:

我已經運行類似的代碼與entlib在高流量的網站,並從未有過這個問題。

如果我殺了所有與數據庫的連接,並獲得生產應用程序備份和運行每次我刷新應用程序,我可以運行該SQL

SELECT DB_NAME(dbid) as 'Database Name', 
COUNT(dbid) as 'Total Connections' 
FROM sys.sysprocesses WITH (nolock) 
WHERE dbid > 0 
GROUP BY dbid 

我可以看到連接的數量與每個積極加大頁面刷新。在本地框上使用相同的連接字符串運行相同的代碼不會導致此問題。此外,如果生產網站關閉,我可以通過Visual Studio啓動網站,並運行它,兩者之間的唯一區別是生產站點啓用了Windows身份驗證,而我的本地副本則沒有。關閉Windows身份驗證似乎對服務器沒有影響。

我絕對沒有線索是什麼導致這個或爲什麼連接沒有在SQL Server中處理。 EntLib對象沒有爲任何東西分解.Close()方法,所以我不能明確地關閉對象。

有什麼想法? 謝謝!

編輯

哇,我剛剛注意到,我從來沒有真正發佈錯誤消息。 Oy公司。實際的連接錯誤是:超時已過期。在從池中獲取連接之前已超時。發生這種情況的原因可能是因爲所有連接池都在使用中,並且達到最大池大小。

+0

請提供一些「更多的代碼」。 – 2010-02-27 04:57:37

+1

鑑於索引對存儲的procs/SELECT等進行了8次調用,每個查詢花費多少時間在數據庫中?難道這個頁面需要相當長的一段時間才能從DB獲取數據,並且如果請求了相同的頁面,它會生成一個新的連接(或從池中)並執行長時間運行的查詢? – shahkalpesh 2010-02-27 05:53:15

+0

更多的代碼並不真正相關,因爲它可以在使用中執行讀取器或執行標量。香草的東西真的。 – dparsons 2010-02-27 15:44:17

回答

0

檢查您正在執行的存儲過程沒有運行到行或表鎖中。此外,如果您可以嘗試在另一臺服務器上部署並檢查應用程序是否會再次抓取。

還嘗試增加SQL服務器的最大允許連接數。

0

它可能是服務器上的配置問題?

如何連接生產服務器上的數據庫?
這可能是一個值得研究的領域。

0

雖然我不知道答案,但我可以建議,由於某些原因,連接在生產中運行時沒有被應用程序關閉。 (說明明顯)

您可能想要檢查Web服務器和SQL Server之間的網絡配置。高延遲網絡可能導致連接未及時關閉。

而且它可能會幫助尋找在下面的MSDN文章的末尾列出的性能計數器: http://msdn.microsoft.com/en-us/library/8xx3tyca%28VS.71%29.aspx

最後,如果沒有別的幫助,我會得到調試和企業庫源代碼,生產和調試您的代碼在企業庫中查找連接未關閉的原因。

愚蠢的問題是你正確地關閉你的DataReader?如果不是這可能是問題,dev和prod之間的行爲差​​異可能是由不同的垃圾收集模式造成的。

0

我會禁用連接池並試圖壓制它(heh)。只需將「Pooling = false」添加到連接字符串即可。

或者,也許你可以添加類似下面的「清理」代碼添加到網頁(封閉敞開的任何連接,當頁面卸載) - 就在「使用」條款:

System.Web.UI.Page page = HttpContext.Current.Handler as System.Web.UI.Page; 
if (page != null) { 
      page.Unload += (EventHandler)delegate(object s, EventArgs e) { 
         try { 
           dbCommand.Connection.Close(); 
         } catch (Exception) { 
         } finally { 
           result = null; 
         } 
      }; 
} 

而且,如果你的SQL服務器和IIS在同一臺機器上(一個真正的性能增強器),確保你已經啓用了「共享內存」協議。