如何实现asp.net 2.0的SqlCacheDependency

如何实现asp.net 2.0的SqlCacheDependency

以前使用Cache的时候,总是当心Cache中数据版本和数据库中数据版本不一致,虽然通过触发器+文件IO实现的文件缓存依赖也可以实现缓存数据的及时更新,但是每个应用产生一个IO文件,不怎么经济,另外触发器性能也不是很高,所以经常在添加删除修改的时候,删除缓存键值来实现,但可能还有遗漏的地方。asp.net 2.0中实现了SqlCacheDependency,本文描述如何在asp.net 2.0实现SqlCacheDependency:
首先,在web.config system.web节点文件里面加上如下代码:


   <caching>
    <sqlCacheDependency enabled="true">
     <databases>
      <add name="AtlasDemoDb" connectionStringName="AtlasDemoDbConnectionString" pollTime="12000"></add>
     </databases>
    </sqlCacheDependency>
   </caching>

这样即配置了一个缓存依赖的数据库,在页面中的ObjectDataSource对象的EnableCaching设置为true.,然后设置SqlCacheDependency属性为AtlasDemoDb:SimpleDemo1,AtlasDemoDb为web.config配置的缓存数据库名称,SimpleDemo1为该数据库下的一个表名。
光是这样,系统还会出现如下问题:


没有为 SQL 缓存通知启用数据库“AtlasDemoDb”。

要为 SQL 缓存通知启用数据库,请使用 System.Web.Caching.SqlCacheDependencyAdmin.EnableNotifications 方法,或命令行工具 aspnet_regsql。要使用此工具,请运行“aspnet_regsql.exe -?”以了解详细信息。
按照上面所说,运行aspnet_regsql.exe 比较烦,可以在Page_Load事件中填写


System.Web.Caching.SqlCacheDependencyAdmin.EnableTableForNotifications(System.Configuration.ConfigurationManager.ConnectionStrings["AtlasDemoDbConnectionString"].ConnectionString, "SimpleDemo1");
这样就可以使用SqlCacheDependency了。

 

 

 

ASP.NET 2.0 中的SqlCacheDependency特性

ASP.NET中的Page Cache是个很有用的东东,只要简单的在页面上方加上一个OutputCache标签,就可以让页面在制定的Duration内直接把自动保存在缓存中的页面内容输出,而不需要让ASP.NET引擎再次执行页面代码,当然,节省这点执行时间并不是最主要的理由,主要理由是如果页面内容是从数据库中取出,那么就可以省去连接数据库、取数据的步骤,这个好处可大了。 m*[3hx _9b
  7B]4|ii8O!{#w
  PageCache有点小小的问题,比如,很多ASP.NET论坛的首页就用了PageCache,所以在一个版里面贴出的最新的帖子并不会马上反映到首页上,而是需要等上一段时间。虽然有点无可奈何,但在某些场合(比如易趣用来显示物品拍卖状态的页面),这种延迟是不允许的。u{)Cu+Q&kp Y
  
U+wq].JL   也即是说,ASP.NET里面的Cache并不能自动根据数据库中相应数据发生了变化,而使相应的Cache过期,ASP.NET 2.0中新增的SqlCacheDependency特性使这成为了可能。(当然,只要我们明白了ASP.NET 2.0中的大致实现方式,我们可以基于ASP.NET 1.0把这个特点实现出来,后面我总结了相应的方法。)
0I8Z cr9J1e7VA   
g J2Eh!RP lQ   要在ASP.NET 2.0中应用SqlCacheDependency特性,步骤如下(基于大家手里的Whidbey PDC版本):LZ6P|4lT
  
[iTgY7Tk LZr   1、  使数据库支持SqlCacheDependencyF8T Z ?/e&iS2E
  在.Net Framework 1.2的安装目录下(通常是WINDOWS/Microsoft.NET/Framework/v1.2.30703),有一个aspnet_regsqlcache.exe,这个命令行工具让我们的SqlServer 7.0或者SqlServer 2000能支持SqlCacheDependency特性,@b6a ],Y1EF9x"C{
  L"}*y T-E M1S$]Xh
  首先:“aspnet_regsqlcache –S 服务器名称 –U 登陆ID –P 密码 –d 数据库名称 –ed”,这个命令使指定数据库支持SqlCacheDependency,
w2h4]lS'k(Kgtf Z6G   [4`n7hOg
  然后我们再加入要追踪的数据表:“aspnet_regsqlcache –S 服务器名称 –U 登陆ID –P 密码 –d 数据库名称 –t 要追踪的数据表的名称 –et”,这个命令使指定的Table支持SqlCacheDependency。
6[%is1Y*?/nA#?-R/l   F8Pz8r&]$_ `
  它在幕后做了什么事情呢?/qJZB8a
  
c VU8yq oEg;A   首先,它在指定的数据库中新建了一个Table,叫做“AspNet_SqlCacheTablesForChangeNotification”,这个表有三个字段,“tableName”记录要追踪的数据表的名称,“notificationCreated”记录开始追踪的时间,“changeId”是一个int类型的字段,每当追踪的数据表的数据发生变化时,这个字段的值就加1。
n_/^*wR#a#Fg   
nU./6[^+W6lgT   它还会在指定的数据库中增加几个存储过程,用来让ASP.NET引擎查询追踪的数据表的情况。
Rw'L-hj%}%aT   6@HGy'Q&Y
  然后,它会给我们要追踪的Table加上几个Trigger,分别对应到Insert、Update、Delete操作,这几个Trigger的语句非常简单,就是把“AspNet_SqlCacheTablesForChangeNotification”表中对应“tableName”字段为这个追踪的表的名称的记录的“changeId”字段加上一个1。
I'p~qSLm   Y/U^v!cxt
   ASP.NET引擎通过执行它加上的存储过程“AspNet_SqlCachePollingStoredProcedure”,这个存储过程直接返回“AspNet_SqlCacheTablesForChangeNotification”表的内容,让ASP.NET引擎知道哪个表的数据发生的变化。默认每500毫秒执行这个存储过程一次,不过可以在web.config里面修改这个间隔时间,我的经验是这个查询操作也是很耗资源的,呵呵。 Mp|4bYG-Mf
   
#F7v-y}$k+SL6l b   2、  web.config配置
?|1A6up;B   
Xj6Uu)B Xe/E/@.d   在web.config里面的配置再简单不过了F];aJ]M
  
-PeS-O7T$O   
aH!rbIpT   &lt;configuration>!m5cod'n#/2[
  
5/#Ep g SCY/i          &lt;!-- 加上合适的数据库连接字符串 -->
|4Z$Ry[0H f    L%@!~.g ]&p/u0|
         &lt;connectionStrings>
(m8y R'zW3r`0aHU&c!x@   
8I$QV_'A5wDn*/+X-G                 &lt;add name="SqlServerConnectionString"
5w$?qY O   5?:_+K y{s@o$[
                connectionString="server=sqlserver1;uid=sa;pwd=Mp j(T]F
  
T.K_7o({0v,v4X   password;database=PortalDB " />kjC6i:k9U4QB
  
/g%a7V+o(J          &lt;/connectionStrings>`EsQZ_5V%n9^
  
"Id6o m ~          &lt;system.web>
;K av/t~/   ME)b-G,_"C
                &lt;!-- 配置Cache一段,使之支持SqlCacheDependency -->
QT%G ]9J3y1I   (y3i5s"N7Y-YB
                &lt;cache>],J%u"tq T
  w4LqES4m'@lv*P'w{
                       &lt;sqlCacheDependency enabled="true" pollTime="500">
em*|1O&{JY'T   h sn bd!/)X C.w
                              &lt;databases> eVRR?,f `7?M
  {-S|]5oMCo:g
                                     &lt;add name=" PortalDB " 6s&q[?3?f RCr9o
  
_)g ra/`X                                              connectionStringName=" SqlServerConnectionString " />|0T:iV3j,aj
  {2c;}a"C3u I3s
                              &lt;/databases>r`,}u"v*`
  
-]a/n] @ pr1xr /j k.p                        &lt;/sqlCacheDependency>1g? c!B]D1S
  9]X/F(es8z
                &lt;/cache>
O | /alps   "S"/)jv/L5B Y
         &lt;/system.web>G6wXK'KbN
  
fD&U'tB%L   &lt;/configuration>
YumWx%Zl   9o/ z)]/6t.|&^
    k@{^%J.R-z%|7j+f.J
   Wz}:jmCP@*l/t
  3、  在页面上的outputCache标签中指定SqlCacheDependency特性:
5a*t,Zk Kf&A)Hq    EWwww5wZ'd o1|
   
[o /2vXa8r   
^{ K(_C5ez   &lt;%@ outputcache duration="9999" varybyparam="None" sqldependency="PortalDB:追踪的数据表名称" %>
8Tf-Vk-mB[@8I   
/hr#mVoB%P@b    
N7g?:Ji   
{%^5}Z_G g@   只要在这个追踪的Table上执行了Insert、Update、Delete操作,数据表上的Trigger就会将数据库中“AspNet_SqlCacheTablesForChangeNotification”表的相应记录的相应“changId”字段值修改,然后ASP.NET引擎就会通过获取新的值来得知追踪的Table的内容发生了变化,自动使这个页面的cache失效。A`T(h/ f9A
  /U#P,?,J#p
   
g }+E b2{D^6/   
q:VHgW&{   后话1、What about Yukon?
| g8Y-g;c;C0}1r;g   
-Wc+V#M7k q    `5d7t:bf.Y5Ma+cSc ^
  a!u+gfx!R9y
  从上面可以知道,SqlServer并没有内置自动追踪数据表的数据变化,然后通知ASP.NET引擎的功能(这是肯定的,SqlServer都出来N久了),所以ASP.NET 2.0的开发组人为的加上了定制的Table、Trigger、StoredProcedure等等来实现数据更改追踪。而Yukon已经不必这么麻烦了,Yukon内置了一个Notification Delivery Service,这个服务会通过WebServer的80端口直接通知一个IIS内置的监听器,然后这个监听器再通知ASP.NET。
6tb gI,Z-aeQ/k   
K/J9A;y(I m    
+oz2ob Q{0p!K j   
R0[i"CV u   而且大家可以注意到,上面描述的那种追踪方式只能追踪到表一级的数据更改,即ASP.NET引擎最后只能得知某个表的数据发生了更改,而到底是哪一条记录发生了更改,是追踪不到的,而Yukon的Notification Delivery Service可以实现记录一级的追踪。'KD)I[,d bga
  
8]u'd!mP;d    
%w"gc'UI}If6_   /k(Y&_2L8Vx!T
  后话2、可以在现在的ASP.NET上实现吗?
"F!}4C;J/M@    ]7hSsS
   1a,x Y!P?/tBu%E
  
W&r4^a-l{9fs9i%ak   当然可以,我们先按照上面讲的第一个步骤(或者自己定义一套规则来实现在数据库中对Table数据变化的追踪),依照葫芦画瓢来自己添加上这些Table、Trigger什么的。
/[yN"M&prCS5O-z   j3QK4wM*d7f6{~
   
4y Ck A"@"N   
%w!^D"dCTV   ASP.NET的PageCache有一个VaryByCustom属性的,这个属性可以实现让我们自己定义“缓存过期”的规则(确切的说,其实它是可以让我们自定义缓存页的版本,但间接可以实现自定义的缓存“过期”啦,呵呵),只要我们在global.asa中重写HttpApplication.GetVaryByCustomString()方法,这个方法根据输入的参数字符串,比如“CheckDBTable=Users”,查询数据库中那个“AspNet_SqlCacheTablesForChangeNotification”(或者你自己定义的某个追踪记录表),直接让这个GetVaryByCustomString()方法返回“changeId”字段的值即可。VaryByCustom的用法MSDN文档上有详细说明。jKg0v&zN:Bj5s
  
5b OB*{ Q&~nSY    
[m/ex!W a d   /B*F De,a h;SFvGYvC
  后话3、GolfClubShack示范程序m#bRn"H kp
  
U*K3e-|*N5Yk)Z   在博客堂前面的某篇文章里面,提供了一个基于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的,安装了好半天,晕...)。
`8/] t qTi   -}d)dD?&sH"L
   
'H-{`/n S2s-B0XP   
xk d"g/u;T   后话4、明天开始上班啦!!!d;Lb#/D/g
  KB3k Z]
  春节假期终于完了,这个春节没有回家,留在深圳过年。今年深圳春节真冷啊,呜呜…家里又没有宽带,只能拨号上网,痛苦不堪。从明天开始,又要开始工作了,不知道要几天才能恢复春节颠倒过来的生物钟。3G Bn$MCqm `&v&h

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值