2010-10-18 73 views
1

我的網站有一個持續的問題,它基本上超時並死亡。我已經到了現在的地步,我必須將應用程序池設置爲每5分鐘自動回收一次,但即使這樣做也失敗了,因爲我剛剛回來工作,並且我的電子郵件收件箱中充滿了4000封電子郵件,錯誤。這段代碼能否殺死我的服務器?

System.Data.SqlClient.SqlException:超時過期。操作完成之前超時的時間或服務器沒有響應。

今天早上我嘗試了一個測試,我在連接字符串上禁用了連接池,但這也不起作用。

現在我想或許這不是泄漏連接的問題,我經歷過所有這些,我認爲這可能與我的網站的核心靜態屬性有關

這裏是其中的一個

public static List<Member> AllMembers 
{ 
    get 
    { 
     if (HttpRuntime.Cache["Members"] != null) 
     { 
      return (List<Member>)HttpRuntime.Cache["Members"]; 
     } 
     else 
     { 
      GetAllMembers(); 
      return (List<Member>)HttpRuntime.Cache["Members"]; 
     } 
    } 
} 

這就是所謂的,每當我想要的成員列表,你可以看到,如果它爲null,則填充緩存,其中會使用到數據庫,如果它不爲null,則它會返回緩存對象。我也有SQLCacheDependancy,它將清除這些緩存對象,以便它再次填充它們。所以這個屬性被稱爲ALOT。

現在,這是一個Web應用程序,併爲我的流量增加了其染色的時候,

難道我的屬性是原因?

任何幫助表示最欣賞

Truegilly

+0

看到GetAllMembers()的代碼比屬性 – LorenVS 2010-10-18 17:41:18

+0

更有用你是否試圖在壓力下監視你的應用程序的內存使用情況?你檢查MS SQL上發生了什麼並監視它嗎?你如何診斷你有什麼問題?或者你只是試圖猜測問題可能存在的地方? – 2010-10-18 17:55:28

回答

6

假設您正確處置的一切,我有一個替代的解釋:

如果緩存爲空/過期和多頁試圖在同一時間打電話AllMembers,則每個頁面可能最終會調用GetAllMembers()同時,減慢數據庫查詢速度。如果通話開始超時,這可能會導致惡性循環。

您可以在您的代碼周圍放置一個lock,因此每個屬性只能創建一個數據庫查詢。下面是我可能會對其進行設置:

private static object _allMembersLock = new object(); 
public static List<Member> AllMembers 
{ 
    get 
    { 
     lock (_allMembersLock) 
     { 
      List<Member> members = (List<Member>)HttpRuntime.Cache["Members"]; 
      if (members == null) 
      { 
       members = GetAllMembers(); 
       HttpRuntime.Cache["Members"] = members; 
      } 
      return members; 
     } 
    } 
} 
+0

最近的編輯現在讓你調用兩次緩存,再加上一個錯誤的結束括號。 – 2010-10-18 18:25:56

+0

@亞當 - 感謝您通知我,我回滾了更改。 @Frank - 當緩存不爲空/過期時,您可能試圖避免鎖定。這是一種合理的方法,但我寧願將這種優化放在這個答案之外。 OP可以優化他/她是否有必要。 – Greg 2010-10-18 18:32:14

1

短短几年秋後算賬:

  1. 你處置所有的SqlCommand的讀者?

  2. 你處置/關閉你的SqlConnection的?

  3. 數據庫能夠處理負載嗎?你有沒有性能問題?

您帖子中的代碼看起來不像是問題。

+0

我擁有的唯一數據庫連接就是我的LINQ 2 SQL數據環境,並且我在每次調用時都使用了它們。:) – JGilmartin 2010-10-18 18:33:46

+0

您的意思是圍繞新的上下文使用? – 2010-10-18 18:34:19

0

我沒有看到任何後衛位置,以防止吸氣觸發GetAllMembers多個併發呼叫。當然你一次只需要一個線程來加載屬性。似乎需要某種lock()

您應該確保刷新緩存的代碼也使用相同的lock()

如果可以從多個服務器調用此代碼,還需要確保支持GetAllMembers的任何數據庫端程序邏輯(存儲過程或來自客戶端的動態SQL)能夠正確處理多個併發讀取器。