ASP.NET 2.0 中的SqlCacheDependency特性
2024-07-10 12:55:58
供稿:網友
本文來源于網頁設計愛好者web開發社區http://www.html.org.cn收集整理,歡迎訪問。asp.net中的page cache是個很有用的東東,只要簡單的在頁面上方加上一個outputcache標簽,就可以讓頁面在制定的duration內直接把自動保存在緩存中的頁面內容輸出,而不需要讓asp.net引擎再次執行頁面代碼,當然,節省這點執行時間并不是最主要的理由,主要理由是如果頁面內容是從數據庫中取出,那么就可以省去連接數據庫、取數據的步驟,這個好處可大了。
pagecache有點小小的問題,比如,很多asp.net論壇的首頁就用了pagecache,所以在一個版里面貼出的最新的帖子并不會馬上反映到首頁上,而是需要等上一段時間。雖然有點無可奈何,但在某些場合(比如易趣用來顯示物品拍賣狀態的頁面),這種延遲是不允許的。
也即是說,asp.net里面的cache并不能自動根據數據庫中相應數據發生了變化,而使相應的cache過期,asp.net 2.0中新增的sqlcachedependency特性使這成為了可能。(當然,只要我們明白了asp.net 2.0中的大致實現方式,我們可以基于asp.net 1.0把這個特點實現出來,后面我總結了相應的方法。)
要在asp.net 2.0中應用sqlcachedependency特性,步驟如下(基于大家手里的whidbey pdc版本):
1、 使數據庫支持sqlcachedependency
在.net framework 1.2的安裝目錄下(通常是windows/microsoft.net/framework/v1.2.30703),有一個aspnet_regsqlcache.exe,這個命令行工具讓我們的sqlserver 7.0或者sqlserver 2000能支持sqlcachedependency特性,
首先:“aspnet_regsqlcache –s 服務器名稱 –u 登陸id –p 密碼 –d 數據庫名稱 –ed”,這個命令使指定數據庫支持sqlcachedependency,
然后我們再加入要追蹤的數據表:“aspnet_regsqlcache –s 服務器名稱 –u 登陸id –p 密碼 –d 數據庫名稱 –t 要追蹤的數據表的名稱 –et”,這個命令使指定的table支持sqlcachedependency。
它在幕后做了什么事情呢?
首先,它在指定的數據庫中新建了一個table,叫做“aspnet_sqlcachetablesforchangenotification”,這個表有三個字段,“tablename”記錄要追蹤的數據表的名稱,“notificationcreated”記錄開始追蹤的時間,“changeid”是一個int類型的字段,每當追蹤的數據表的數據發生變化時,這個字段的值就加1。
它還會在指定的數據庫中增加幾個存儲過程,用來讓asp.net引擎查詢追蹤的數據表的情況。
然后,它會給我們要追蹤的table加上幾個trigger,分別對應到insert、update、delete操作,這幾個trigger的語句非常簡單,就是把“aspnet_sqlcachetablesforchangenotification”表中對應“tablename”字段為這個追蹤的表的名稱的記錄的“changeid”字段加上一個1。
asp.net引擎通過執行它加上的存儲過程“aspnet_sqlcachepollingstoredprocedure”,這個存儲過程直接返回“aspnet_sqlcachetablesforchangenotification”表的內容,讓asp.net引擎知道哪個表的數據發生的變化。默認每500毫秒執行這個存儲過程一次,不過可以在web.config里面修改這個間隔時間,我的經驗是這個查詢操作也是很耗資源的,呵呵。
2、 web.config配置
在web.config里面的配置再簡單不過了
<configuration>
<!-- 加上合適的數據庫連接字符串 -->
<connectionstrings>
<add name="sqlserverconnectionstring"
connectionstring="server=sqlserver1;uid=sa;pwd=
password;database=portaldb " />
</connectionstrings>
<system.web>
<!-- 配置cache一段,使之支持sqlcachedependency -->
<cache>
<sqlcachedependency enabled="true" polltime="500">
<databases>
<add name=" portaldb "
connectionstringname=" sqlserverconnectionstring " />
</databases>
</sqlcachedependency>
</cache>
</system.web>
</configuration>
3、 在頁面上的outputcache標簽中指定sqlcachedependency特性:
<%@ outputcache duration="9999" varybyparam="none" sqldependency="portaldb:追蹤的數據表名稱" %>
只要在這個追蹤的table上執行了insert、update、delete操作,數據表上的trigger就會將數據庫中“aspnet_sqlcachetablesforchangenotification”表的相應記錄的相應“changid”字段值修改,然后asp.net引擎就會通過獲取新的值來得知追蹤的table的內容發生了變化,自動使這個頁面的cache失效。
后話1、what about yukon?
從上面可以知道,sqlserver并沒有內置自動追蹤數據表的數據變化,然后通知asp.net引擎的功能(這是肯定的,sqlserver都出來n久了),所以asp.net 2.0的開發組人為的加上了定制的table、trigger、storedprocedure等等來實現數據更改追蹤。而yukon已經不必這么麻煩了,yukon內置了一個notification delivery service,這個服務會通過webserver的80端口直接通知一個iis內置的監聽器,然后這個監聽器再通知asp.net。
而且大家可以注意到,上面描述的那種追蹤方式只能追蹤到表一級的數據更改,即asp.net引擎最后只能得知某個表的數據發生了更改,而到底是哪一條記錄發生了更改,是追蹤不到的,而yukon的notification delivery service可以實現記錄一級的追蹤。
后話2、可以在現在的asp.net上實現嗎?
當然可以,我們先按照上面講的第一個步驟(或者自己定義一套規則來實現在數據庫中對table數據變化的追蹤),依照葫蘆畫瓢來自己添加上這些table、trigger什么的。
asp.net的pagecache有一個varybycustom屬性的,這個屬性可以實現讓我們自己定義“緩存過期”的規則(確切的說,其實它是可以讓我們自定義緩存頁的版本,但間接可以實現自定義的緩存“過期”啦,呵呵),只要我們在global.asa中重寫httpapplication.getvarybycustomstring()方法,這個方法根據輸入的參數字符串,比如“checkdbtable=users”,查詢數據庫中那個“aspnet_sqlcachetablesforchangenotification”(或者你自己定義的某個追蹤記錄表),直接讓這個getvarybycustomstring()方法返回“changeid”字段的值即可。varybycustom的用法msdn文檔上有詳細說明。
后話3、golfclubshack示范程序
在博客堂前面的某篇文章里面,提供了一個基于asp.net 2.0的golfclubshack站點的示范程序,是非常好的東東,在那個里面可以看到包括sqlcachedependency在內的眾多asp.net 2.0的特性的體現。現在網上完整的asp.net 2.0的示范程序不多,聽說ms內部已經把ibuyspy移植到asp.net 2.0上面了,不知詳情如何。而ms還在alpha階段的aspnetforums 2.0還是基于.net framework 1.1的(我以前一直是以為是基于最新的asp.net 2.0的,安裝了好半天,暈...)。
后話4、明天開始上班啦!!!
春節假期終于完了,這個春節沒有回家,留在深圳過年。今年深圳春節真冷啊,嗚嗚…家里又沒有寬帶,只能撥號上網,痛苦不堪。從明天開始,又要開始工作了,不知道要幾天才能恢復春節顛倒過來的生物鐘。