Oracle支撐的asp.net2.0應用中自主實現數據依賴緩存

項目中有一些報表,本身速度就不太快,遇到數據量大的情況,更是讓人抓狂,用戶也提出了報表速度慢的問題,於是想着如何實現報表的數據依賴緩存,即將報表數據緩存,當數據發生改變時,再重新獲取數據。

 

最簡單的方法,是在顯示報表的aspx頁面第一行加上形如<%@ OutputCache Duration="600" VaryByParam="some_param" %>的一句,直接讓頁面緩存10分鐘。但是這種辦法無法監測數據的改變,無法滿足報表的時效性。

 

ASP.NET2.0提供了緩存依賴技術,可以讓緩存監視文件、目錄的變化,從而更新緩存。這種技術若是與SQL Server結合使用,貌似會很方便,可是我們的項目用的是Oracle,所以無法考慮。

 

此外,ASP.NET2.0中還可以自己設定應用程序數據緩存,也就是把數據緩存起來,不用每次都查詢數據庫。

 

應用程序數據緩存技術,可以讓我的報表頁面不用每次都做數據庫查詢,從而提高效率。在設定這種緩存時,可以指定絕對過期時間、相對過期時間,以及緩存更新的依賴項。

 

理想的狀態,應該是當數據在別的頁面有更新時,就想辦法“通知”報表頁面,讓它重新做數據庫查詢。既然可以指定緩存依賴於文件,那麼就可以考慮,當數據有變化時,就更新某個文件,這樣依賴於這個文件的緩存就會失效,從而引發從數據庫重新查詢數據了。

 

有了這個思路,實現起來也就不難了。

 

具體來說,我做的這個系統是個任務流轉的系統,報表也是對任務的數據統計。

 

那麼,我就在系統中建立一個Cache目錄,專門存放緩存所依賴的文件。當新建一個任務時,就以該任務的ID號爲文件名,新建一個擴展名爲.cache的文件(當然,這個擴展名是我自定義的,任意),然後向其中寫入當前的系統時間(當然,寫入什麼都行,只要是能更新這個文件)。其它的能夠改變任務相關的數據的地方,也同時修改相應緩存文件的內容即可。

 

接下來,在報表頁面,用類似以下代碼實現緩存:

 

DataTable dt = (DataTable)Cache["rptPingFen"+strTaskID + Session["userEntID"].ToString()];
if (dt == null)
{
    dt = Reports.rptPingFen( strTaskID, Session["userEntID"].ToString() );
    string strCacheFile = Server.MapPath( "~/Cache/" + strTaskID + ".cache" );
    if (System.IO.File.Exists( strCacheFile ))
        Cache.Insert( "rptPingFen" + strTaskID + Session["userEntID"].ToString(), dt, new System.Web.Caching.CacheDependency( strCacheFile ), System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromSeconds( 600 ) );
}

 

上面這段代碼的大意是:在緩存中找一下鍵爲"rptPingFen"+strTaskID + Session["userEntID"].ToString()的項,轉換爲DataTable。若有,就用它綁定報表,也就不用從數據庫查詢數據了;若沒有該項,則建立鍵爲"rptPingFen"+strTaskID + Session["userEntID"].ToString()的緩存,其內容爲從數據庫查詢數據的結果的DataTable,並設定其沒有絕對到期時間,而是被訪問後的10分鐘後失效。

 

關鍵之處在於參數System.Web.Caching.CacheDependency( strCacheFile ),它指明瞭所建立的緩存依賴於文件strCacheFile,若發現該文件有變化,則緩存失效。

 

至此,由Oracle支撐的ASP.NET應用的數據依賴緩存已經實現了,還是比較簡單的辦法。

 

PS:若時間允許,完全可以將緩存依賴文件(.cache文件)改造爲某種日誌文件,既對數據變化做日誌,又可作爲監視數據變化的緩存依賴文件,可一舉兩得。

發佈了171 篇原創文章 · 獲贊 2 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章