我開始之前,我無法找到任何其他資源來回答我的問題,最接近的是:
Calling a stored procedure simultaniously from multiple threads in asp.net and sql server 2005
但它沒有回答我的具體問題/關注。多asp.net請求調用相同的SQL Server 2005存儲過程
基本上,我有一個龐大的.NET網絡應用程序,每天處理數百萬個請求。
假設:
- 所有有關存儲過程是簡單的GET存儲過程(例如,選擇[SOMETHING] FROM [某處] INNER JOIN [別的]等....)
- 所有數據永遠不會改變(它會不時變化,爲了我的情況,假設它不會)
- 無論什麼原因,緩存最初都是空的。
問題的方法:
我檢查應用程序緩存中的對象的存在。如果存在,我只需返回它。如果對象不在高速緩存中,則會對數據庫執行臨時調用以查找此數據。一旦該sproc返回,該數據將被添加到緩存中,然後返回。
重負載下我有一點性能問題,我想清除。
這裏是我的情況:
- 用戶A進入此方法。
- 數據不在緩存中,sproc被調用。
- 用戶B進入此方法(雖然sproc仍在運行)。
- 數據不在緩存中,sproc被調用。
- 沖洗並反覆重複。
在重負載下,這些可能會產生相當多的併發和冗餘活動spid。我試圖找出解決這個問題的最佳方法。很明顯,我可以放入一個sp_getAppLock,但這些請求仍然會結束1)放入sproc,2)必須觸發完全相同的查詢。我可以鎖定特定於該確切查詢的對象,並將其包裝在緩存檢查中。但是如果我這樣做,我可能會爲一些大規模的線程爭奪和僵局而打開大門。
我不得不假設有人已經處理過這種情況,我希望有一個合適的解決方案。現在我可以提出的最佳解決方案是應用程序鎖定,但我真的很想知道任何人是否有更好的選擇。也許是組合的東西,比如SQL應用程序鎖定和消息傳遞(傳統或非傳統),在鎖定成功之後,剛剛發佈的任何剛剛發佈的嘗試將結果集(從何處?)拉下來,而不是重新執行整個其餘部分。
編輯:
所以按照這個....如果我鎖定或「等待」無論是緩存或存儲過程的調用,重負載下有可能,如果一個元素沒有被緩存,而該方法(或存儲過程)生成要緩存的對象可能最終花費比預期更長的時間。雖然這是旋轉,線程將不得不等待。通過等待,唯一的方法(至少我知道)是鎖定或旋轉。
難道不可能讓線程池耗盡或鎖定所有可用請求並強制請求排隊?這是我的恐懼和驅使我去考慮將應用程序層移動到數據庫中的事情。上次我們嘗試鎖定緩存時,我們的網絡盒遭受了嚴重的CPU峯值,因爲這些線程長時間處於鎖定狀態。雖然我相信當時我們沒有使用Monitor.Enter/Monitor.Exit(或者只是鎖定(){})。無論哪種方式,任何人都沒有在這方面的任何細節或經驗?出於這個原因,我知道鎖定長時間運行的進程通常是不好的形式。如果我可以避免阻止用戶請求放入請求隊列,因爲我全部脫離線程或所有活動請求都被鎖定,我會忍受將重複內容加載到緩存中。
或者,也許這只是晚了,我在想這個。我以一個幾乎燦爛的「啊哈」時刻開始了我的一天。但現在我只是繼續猜測自己。
這是一個ASP.NET問題,而不是T-SQL。數據庫服務器如何知道你爲什麼稱它? – gbn 2011-12-29 18:28:41
這是一個多線程/資源爭用問題。它不是C#,不是asp.net,而不是sql。 – 2011-12-29 18:39:03
確實如此。雖然這是一個多線程/資源爭用問題,恰好處理所有這些元素。那裏是我使用這些標籤的原因。 – John 2011-12-29 18:47:19