我有一個具有相當慢的搜索功能的ASP.NET網站,我想通過將查詢作爲緩存鍵添加到緩存一小時來提高性能:在ASP.NET中正確執行鎖定
using System;
using System.Web;
using System.Web.Caching;
public class Search
{
private static object _cacheLock = new object();
public static string DoSearch(string query)
{
string results = "";
if (HttpContext.Current.Cache[query] == null)
{
lock (_cacheLock)
{
if (HttpContext.Current.Cache[query] == null)
{
results = GetResultsFromSlowDb(query);
HttpContext.Current.Cache.Add(query, results, null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
}
else
{
results = HttpContext.Current.Cache[query].ToString();
}
}
}
else
{
results = HttpContext.Current.Cache[query].ToString();
}
return results;
}
private static string GetResultsFromSlowDb(string query)
{
return "Hello World!";
}
}
假設訪問者A進行搜索。緩存爲空,設置鎖定並從數據庫請求結果。現在,訪問者B帶有不同的搜索:在訪問者A的搜索完成之前,訪問者B是否必須等待鎖定?我真正想要的是B立即調用數據庫,因爲結果會不同,數據庫可以處理多個請求 - 我只是不想重複昂貴的不必要的查詢。
這種情況下正確的方法是什麼?
是真正的查詢那麼貴和/或網站那麼忙,你買不起幾多餘的重複查詢每小時一次? (並且只有在兩次或更多次查詢幾乎同時在緩存過期時同時觸發您的方法時,纔會出現這種情況。) – LukeH 2011-04-07 09:22:47
如果您的數據庫不支持多個讀取訪問,則可以實施消息查詢,以便DB服務A,然後DB服務B ...在服務時檢查緩存。 – Winfred 2011-04-07 09:28:05
@LukeH,在那個特定的數據庫中發生了很多事情,所以我們可以減輕負擔是值得的。 – 2011-04-07 09:28:43