在ASP
NET中
Cache類最酷的特點是它能根據各種依賴來良好的控制自己的行為
以文件為基礎的依賴是最有用的
文件依賴項是通過使用 Cache
Insert 並提供引用文件的 CacheDependency 對象添加的
Cache
Insert(
MyData
Source
new CacheDependency(Server
MapPath(
authors
xml
)));
但是當我們想讓緩存根據數據庫的變化而失效的時候
應該怎麼做呢 – 這種情景在很多應用程序中都存在
沒有為監視數據庫表的變化提供內在的直接緩存支持
利用SQL Server的不常用的系統存儲過程sp_makewebtask
是可以達到這個目的的
這個存儲過程本來是用作從查詢中生成web頁面的
但是我們只要稍作修改
在觸發器中使用它
我們就可以取得一個合理有效的途徑
當數據庫某張表的記錄被更新
刪除或者修改時來修改某個特定的文件
這樣會使在CacheDependency實例中的文件監視進程偵測到文件的變化
從而使緩存失效
事實上
因為CacheDependency 類工作在UNC文件協議上
我們可以在整個Web Farm上部署這個解決方案
Web Farm上每台機器上的應用程序副本都會通過UNC文件路徑來監視WebFarm中某台單個機器上的同一個文件
廢話少說
讓我們創建一個簡單的web應用程序
來演示它是如果工作的
首先
我們將會使用我們SQL Server中都信賴的Northwind范例數據庫
創建一個簡單的DataGrid來顯示Employees表中的記錄
我們要做的第一件事情就是創建觸發器
CREATE TRIGGER WriteCacheDepFile ON [dbo]
[Employees]
FOR INSERT
UPDATE
DELETE
AS
EXEC sp_makewebtask
\\peter\C$\Cache\mycache
txt
SELECT top
FirstName FROM employees
以上存儲過程就是簡單的告訴SQL Server
如果Employee表發生任何變動
就根據一個簡單的查詢來更新
mycache
txt
文件
有這個簡單的查詢語句其實足夠了
只要它是一個有效的T
SQL語句
SQL Server會很樂意的去更新那個文件
接下來
我們需要創建一個目錄
並設為共享
你可能要更新該文件的訪問權限
以使它可以被寫入
注意
我這裡使用的是管理員共享
C$
另外
你還需要創建一個空的文本文件
mycache
txt
好
現在可以創建我們的應用程序了
首先
在nfig文件中輸入依賴文件名稱
這樣做可以使我們在修改依賴文件的時候不需要重新部署應用程序
在nfig文件的根部
添加appSettings配置節
現在
讓我們在Global類中建立緩存機制
這樣我們不需要在任何頁面中編寫特定的代碼
[C#]
public class Global : System
Web
HttpApplication
{
Cache _cache =null;
public static bool blnReflash = false;
public const string ConnStr =
server=localhost;database=Northwind;uid=sa;pwd=
;
public const string strSQL =
SELECT EmployeeID
lastname
firstname FROM
Employees
;
protected void Application_Start(Object sender
EventArgs e)
{
_cache = Context
Cache;
RefreshCahe(null
null
null);
}
protected void Session_Start(Object sender
EventArgs e)
{
if(HttpContext
Current
Cache[
Employees
]==null)
RefreshCache(null
null
);
}
static void RefreshCache(string key
object item
CacheItemRemoveReason reason)
{
SqlDataAdapter adapter = new SqlDataAdapter(strSQL
ConnStr);
DataSet ds = new DataSet();
adapter
Fill(ds
Employees
);
CacheItemRemovedCallback onRemove = new CacheItemRemovedCallback(RefreshCache);
string depFile= ConfigurationSettings
AppSettings[
dependencyFile
]
ToString();
HttpContext
Current
Cache
Insert(
Employees
ds
new CacheDependency(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
在WebForm
aspx中
我演示了如何使用它
[C#]
private void Page_Load(object sender
System
EventArgs e)
{
//保證緩存非空
如果為空
則填充它
if(Cache[
Employees
] == null)
cacheStatus
Text =
Cache Refreshed at
+ DateTime
Now
ToLongTimeString();
else
cacheStatus
Text =
DataSet from Cache
;
DataSet ds = (DataSet)Cache[
Employees
];
DataGrid
DataSource= ds
Tables[
];
DataGrid
DataBind();
}
現在
如果你請求這個頁面
它將會每次成功的顯示從從Cache中取得的DataSet
如果你保持浏覽器打開
同時打開SQL Server的查詢分析器
選擇Northwind數據庫
執行SQL語句
Update Employees set Lastname =
Davovlieu
where EmployeeID =
更新表中的記錄
然後重新請求該頁面
你將會看到緩存已經失效並刷新
譯者按
關於基於數據庫的緩存依賴
gotdotnet上也有一個用DataSet實現的(Rob Howard 實現) ASP
NET Cache Invalidation on Database Change
目前在ASP
NET
版本沒有非常自然的解決方案
值得欣慰的是
隨Whidbey一起發布的ASP
NET
還有Yuku
從數據層提供了一個不錯的實現
讓我們拭目以待!
下面的工程是Visual Studio
NET
格式
下載本文工程
From:http://tw.wingwit.com/Article/program/net/201311/13571.html