ASP.NET數據庫緩存依賴
在ASP.NET中,Cache類最酷的特點是它能根據各種依賴來良好的控製自己的行為。以文件為基礎的依賴是最有用的,文件依賴項是通過使用Cache.Insert並提供引用文件的CacheDependency對象添加的Cache.Insert("MyData",Source,newCacheDependency(Server.MapPath("authors.xml")));
但是當我們想讓緩存根據數據庫的變化而失效的時候,應該怎麼做呢–這種情景在很多應用程序中都存在。Asp.net沒有為監視數據庫表的變化提供內在的直接緩存支持。利用SQLServer的不常用的係統存儲過程sp_makewebtask,是可以達到這個目的的,這個存儲過程本來是用作從查詢中生成web頁麵的,但是我們隻要稍作修改-在觸發器中使用它,我們就可以取得一個合理有效的途徑,當數據庫某張表的記錄被更新,刪除或者修改時來修改某個特定的文件,這樣會使在CacheDependency實例中的文件監視進程偵測到文件的變化,從而使緩存失效。事實上,因為CacheDependency類工作在UNC文件協議上,我們可以在整個WebFarm上部署這個解決方案,WebFarm上每台機器上的應用程序副本都會通過UNC文件路徑來監視WebFarm中某台單個機器上的同一個文件
廢話少說,讓我們創建一個簡單的web應用程序,來演示它是如果工作的。首先,我們將會使用我們SQLServer中都信賴的Northwind範例數據庫。創建一個簡單的DataGrid來顯示Employees表中的記錄.我們要做的第一件事情就是創建觸發器。
CREATETRIGGERWriteCacheDepFileON[dbo].[Employees]
FORINSERT,UPDATE,DELETE
AS
EXECsp_makewebtask'//peter/C$/Cache/mycache.txt','SELECTtop1FirstNameFROMemployees'
以上存儲過程就是簡單的告訴SQLServer,如果Employee表發生任何變動,就根據一個簡單的查詢來更新”mycache.txt”文件,有這個簡單的查詢語句其實足夠了,隻要它是一個有效的T-SQL語句,SQLServer會很樂意的去更新那個文件。
接下來,我們需要創建一個目錄,並設為共享。你可能要更新該文件的訪問權限,以使它可以被寫入,注意,我這裏使用的是管理員共享”C$”.另外,你還需要創建一個空的文本文件,"mycache.txt".
好,現在可以創建我們的應用程序了。首先,在web.config文件中輸入依賴文件名稱,這樣做可以使我們在修改依賴文件的時候不需要重新部署應用程序。
在web.config文件的根部,添加appSettings配置節:
現在,讓我們在Global類中建立緩存機製,這樣我們不需要在任何頁麵中編寫特定的代碼
[C#]
publicclassGlobal:System.Web.HttpApplication
{
Cache_cache=null;
publicstaticboolblnReflash=false;
publicconststringConnStr="server=localhost;database=Northwind;uid=sa;pwd=";
publicconststringstrSQL="SELECTEmployeeID,lastname,firstnameFROM
Employees";
protectedvoidApplication_Start(Objectsender,EventArgse)
{
_cache=Context.Cache;
RefreshCahe(null,null,null);
}
protectedvoidSession_Start(Objectsender,EventArgse)
{
if(HttpContext.Current.Cache["Employees"]==null)
RefreshCache(null,null,0);
}
staticvoidRefreshCache(stringkey,objectitem,CacheItemRemoveReasonreason)
{
SqlDataAdapteradapter=newSqlDataAdapter(strSQL,ConnStr);
DataSetds=newDataSet();
adapter.Fill(ds,"Employees");
CacheItemRemovedCallbackonRemove=newCacheItemRemovedCallback(RefreshCache);
stringdepFile=ConfigurationSettings.AppSettings["dependencyFile"].ToString();
HttpContext.Current.Cache.Insert("Employees",ds,newCacheDependency(depFile),
Cache.NoAbsoluteExpiration,Cache.NoSlidingExpiration,
CacheItemPriority.High,onRemove);
blnReflash=true;
}
}
就像上麵看到的一樣,我們定義了一個Cache類型的_cache對象,在Application_Start方法中,我們把當前的Cache實例賦給它,然後調用RefreshCache方法去填充該對象。RefreshCache實際上是一個靜態的委托回調方法,它所做的就是簡單的從Empoyees表中取得一個DataSet,然後創建CacheItemRemovedCallback類型的委托OnRemove,使其指向RefreshCache方法,這樣當被監控的文件變化時,也就是緩存失效時,就會調用該委托,刷新緩存中的數據。
最後我們把DataSet連同OnRemove委托一起插入到緩存中,在Session_Start中,為了“保險“,我另外添加了一個判斷來調用RefreshCache方法填充緩存。
到這裏,我們應用程序就創建好了,在任何頁麵中都可以訪問到緩存的DataSet。在WebForm1aspx中,我演示了如何使用它。
[C#]
privatevoidPage_Load(objectsender,System.EventArgse)
{
//保證緩存非空,如果為空,則填充它
if(Cache["Employees"]==null)
cacheStatus.Text="CacheRefreshedat"+DateTime.Now.ToLongTimeString();
else
cacheStatus.Text="DataSetfromCache";
DataSetds=(DataSet)Cache["Employees"];
DataGrid1.DataSource=ds.Tables[0];
DataGrid1.DataBind();
}
現在,如果你請求這個頁麵,它將會每次成功的顯示從從Cache中取得的DataSet,如果你保持瀏覽器打開,同時打開SQLServer的查詢分析器,選擇Northwind數據庫,執行SQL語句'UpdateEmployeessetLastname='Davovlieu'whereEmployeeID=1',更新表中的記錄,然後重新請求該頁麵,你將會看到緩存已經失效並刷新。
最後更新:2017-04-02 00:06:33