2009-01-23 246 views
4

會發生什麼,如果一個用戶試圖讀取HttpContext.Current.Cache [關鍵],而另一人試圖刪除對象HttpContext.Current.Cache.Remove(鍵)在同一時間?ASP.NET緩存對象讀寫

想想幾百個用戶正在讀取緩存並試圖同時清理一些緩存對象。發生了什麼,它是否線程安全?

是否有可能在緩存中創建數據庫感知業務對象?

回答

1

如果代碼無法獲取對象,則返回nothing/null。

如果您有機會頻繁地刪除對象,爲什麼還要打擾緩存對象?最好設置到期時間,如果對象不在緩存中,則重新加載對象。

你能解釋一下「數據庫感知對象」嗎?你的意思是一個sql cache dependency,或者只是一個有關db連接信息的對象?

編輯: 對第3條評論的回覆。

我想我們在這裏錯過了一些東西。讓我解釋我認爲你的意思,你可以告訴我,如果它的權利。

  1. UserA檢查緩存中的對象 (「resultA」),但未找到它。
  2. UserA運行查詢。結果是 緩存爲「resultA」5分鐘。
  3. UserB檢查緩存中的對象 (「resultA」)並確實找到它。
  4. 用戶B使用緩存的對象「resultA」

如果是這樣的話,那麼你不需要一個SQL緩存依賴。

3

內置的ASP.Net緩存對象(http://msdn.microsoft.com/en-us/library/system.web.caching.cache.aspx)是線程安全的,因此在多線程環境中插入/刪除操作本質上是安全的。

將任何對象放入緩存中的主要要求是必須是可序列化的。所以是的,你的數據庫感知的業務對象可以進入緩存。

+1

僅僅因爲對象是線程安全的,並不保證對象將被鎖定或可用,並且Serializable與DB知曉對象無關 – StingyJack 2009-01-23 20:59:19

+1

正確,線程安全並不能防止死鎖。但是,HttpRuntime Cache確實具有內置保護以確保可用性。 但*進入緩存的任何*對象必須是可序列化的。我的觀點是,緩存中的對象的數據庫感知是無關​​緊要的。 – jro 2009-01-24 16:27:10

+0

同意。感謝澄清。 – StingyJack 2009-01-26 13:05:41

0

嗯,我有一個代碼來填充緩存:

string cacheKey = GetCacheKey(filter, sort); 
if (HttpContext.Current.Cache[cacheKey] == null) 
{ 
    reader = base.ExecuteReader(SelectQuery); 
    HttpContext.Current.Cache[cacheKey] = 
    base.GetListByFilter(reader, filter, sort); 
} 
return HttpContext.Current.Cache[cacheKey] as List<CurrencyDepot>; 

,並在表中更新下面執行清理代碼:

private void CleanCache() 
{ 
    IDictionaryEnumerator enumerator = 
    HttpContext.Current.Cache.GetEnumerator(); 
    while (enumerator.MoveNext()) 
    { 
    if (enumerator.Key.ToString().Contains(_TableName)) 
    { 
     try { 
     HttpContext.Current.Cache.Remove(enumerator.Key.ToString()); 
     } catch (Exception) {} 
    } 
    } 
} 

這是使用造成麻煩?