都是緩存惹得禍

首發於:都是緩存惹得禍  

最近項目開發完成了,在試運行時,發現幾個由於緩存設置不當導致的問題,寫下來,和各位探討一下,不妥之處,望指點一二
一,頁輸出緩存導致的問題
  問題描述:在一個網站首頁,有幾個用戶登錄的框框,登陸後要隱藏起來,並顯示用戶的相關信息,因爲這個是首頁,考慮到訪問量很大,而且頁面的更新也比較少,所以使用<%@ OutputCache Duration="60" VaryByParam="none"%>來啓用頁輸出緩存,但發現一個問題:第二用戶用戶登錄後,看到確是第一個用戶的登陸信息
 
  問題分析:頁輸出緩存是在第一個用戶發出請求後,把從動態頁中生成的靜態內容緩存在服務器的高速緩衝中,在設定的時間內,後續的請求都從該緩存中響應,所以就有可能出現上面描述的問題了

  問題解決:不使用頁輸出緩存,這個是爲個性化犧牲性能,但爲了儘量減少性能
損失,除了在中間成做數據緩存外,還要對頁面通過用戶控件拆分,進行頁片斷緩存

  總結:通過這個問題,我發現凡是需要顯示個性化信息的地方,通常都不合適做頁輸出緩存,針對這個問題,爲了提高性能,我有幾個想法:
   1,登陸區域儘量考慮放在另一個頁面中進行登陸 ;
   2,需要個性化的信息放在另一頁,然後iframe進來,這樣頁面可以同時兼顧個性     話和性能,適合個性化信息比較少的情況 ;
   3,如果頁面確實不能做頁輸出緩存,那要考慮是否可以做頁片斷緩存,始終要
   考慮是否應該進行數據緩存的問題

二,數據緩存引起的問題
  問題描述 :
   我們對從數據庫中獲取到的年紀信息進行緩存,代碼如下:
   public static GradeCollection GetGrades()
   {
       string cacheKey = "GradeCollection" ;
       if (HttpRuntime.Cache[cacheKey] == null)
           HttpRuntime.Cache[cacheKey] = DataProvider.GetGrades() ;
       return (GradeCollection)HttpRuntime.Cache[cacheKey] ;
   }
   然後把數據加工後再邦定到一個dropdownlist中:
   GradeCollection gc = GetGrades() ;
   Grade g = new Grade() ;
   g.GradeName = "所有年級" ;
   gc.Insert(0,g) ;
   問題就出來,運行完這段代碼,別的地方再GetGrades()獲得數據將會是被改動
   過的數據,這並不是我們所期望的

   問題解決 :不能對獲取的數據進行改動,我們的目的是在dropdownlist上加上一個“所有年級”項,這個是可以在控件上實現的,就不應該對數據加工了,但問題是我們無法確定其他地方GetGrades()後會進行什麼操作,一個方法的數據安全不
應該依賴於調用者的,所以需要對做了數據緩存的地方進行改動:
   public static GradeCollection GetGrades()
   {
       string cacheKey = "GradeCollection" ;
       if (HttpRuntime.Cache[cacheKey] == null)
           HttpRuntime.Cache[cacheKey] = DataProvider.GetGrades() ;
       GradeCollection gc = (GradeCollection)HttpRuntime.Cache[cacheKey] ;
       return gc.DeepClone() ;//返回gc的深拷貝,具體方法略
   }
   雖然這樣做,佔用的內存會更多,性能上有折損,但數據更安全,程序更健壯了
同時也比不使用數據緩存性能更高一些
  
   但同時得承認,這不是一個很好的解決方法,不知道各位大蝦有沒有遇到這類問題
你是怎麼解決的?望指點一二,不勝感激了!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章