缓存依赖、数据库缓存依赖学习以及在LinQ当中使用缓存依赖


导读:

◆缘起
◆缓存简述
◆缓存依赖简述
◆自定义缓存依赖分析
◆数据库缓存依赖学习
◆LINQ缓存依赖实现
◆文档更新说明
◆附:缓存依赖研究项目源码(包括数据库)
◆参考资料

 

一、缘起

(本文发布于博客园,作者在博客园的博客地址是:http://www.cnblogs.com/xpnew/ 原文地址: http://www.cnblogs.com/xpnew/archive/2012/05/03/LinQCacheDependency.html ,由于转载会造成图片、格式丢失,以及不能获得文档的最后更新,所以在此特别声明)
最近做的一个客户项目,客户提出的要求是参数可定制,例如会员积分达到3000可以升一档。
实现这个需求,其实很容易,只要把相关的参数都写到数据库或者xml文件当中,使用的时候再读出然后作比较就可以了。
从性能优化的角度来讲,当然不能是每次使用的时候都重新读取一遍。
在asp时代,优化性能的一个关键就是把数据保存到Application和Session当中,到了asp.net时代,就提供了一个“更好”的工具:Cache。
以前就研究过Cache,不过因为需要优化的数据较少,所以仍然使用Application。
做到这个项目,虽然需要缓存的数据不多,但是因为通过缓存依赖可以“及时”获得更新,所以决定下大力气仔细研究一下。
我现在做东西使用的是LINQ,并且分成DALEntery、DAL、BLL、WEB这4层,所以不能直接使用数据库缓存依赖,于是在网站找了好久,都没有找到在LINQ当中使用缓存依赖的技术资料,最后没办法,只好研究其它的缓存依赖方式。
写出这篇笔记之前,我的学习路线是:先看MSDN当中Asp.net当中使用缓存的部分,然后一些关于“自定义缓存”方面的技术博客,最后是“数据库缓存依赖”的技术资料并且动手做了一些实验,然后是总结分析。

二、缓存简述

缓存的作用就减少对原始数据的访问次数,提高性能。

缓存的使用方法,就是用Add或者Insert方法,把对象存储到缓存当中。

 

缓存的技术需要研究超时、页面缓存、缓存依赖等细节。


三、缓存依赖简述

缓存依赖就是在正常的缓存到期之前,提前获知原始数据已经更改,以最快的速度保持数据的同步。


缓存依赖有几种形式:

文件、其它缓存、多对象依赖、数据库缓存依赖、自定义缓存依赖

四、自定义缓存依赖分析

从网站看到了一堆资料之后,可以总结出以下几点:

1、派生于CacheDependency


2、通过计时器来轮询


3、需要自己实现比较和判定,以确定缓存是否已经更新/修改


五、数据库缓存依赖学习

《系统缓存全解析6:数据库缓存依赖》阅读了两遍之后,我自己动手做了一下实验,实验的结果和文章描述的完全一致。

为了进一步的理解,我又在数据库里创建了“新闻”、“案例”两个表,作为对比对象。

其中新闻使用了缓存,超时设置为15分钟,案例没有缓存。

实验是在两个页面时行的,一个是list,一个是Insert。前者用GrideView控件显示产品、新闻、案例的列表,后者用DetailsView控件插入数据。

 

实验的现象一:

1、新添加的产品,立刻能显示在列表页上。

2、新添加的新闻,不会立刻显示在列表页上,直到15分钟之后才出现。

3、新添加的案例,立刻能显示在列表页面上。


初步结论:使用缓存依赖,能够保持数据的同步。

实验的现象二:

新添加了产品,立即在列表页面刷新,列表页面有时候不能立即显示。


进一步结论:

缓存依赖,是“理论”上的即时同步,并非真的分秒不差。究其根源,应该是因为缓存依赖,其实是基于轮询的方式实现的。


然后打开数据库,研究了一下,数据库缓存依赖的原理终于真像大白了:

1、首先是在数据库创建了一系列的存储过程

2、然后是在数据库创建了一个表:AspNet_SqlCacheTablesForChangeNotification

3、在需要监视的表上创建触发器:[P_Product_AspNet_SqlCacheNotification_Trigger]

4、每次被监视的表上修改之后,都要通过触发器=》存储过程=》来修改表AspNet_SqlCacheTablesForChangeNotification相应的记录。

5、Asp.net通过web.config的设置,轮询数据库里的表AspNet_SqlCacheTablesForChangeNotification

6、根据在Cache当中指定了的缓存依赖,比较表名(AspNet_SqlCacheTablesForChangeNotification的[tableName]字段)对应的changeId是否发生变化,判断缓存源数据是否发生变化,然后决定缓存项提前过期。


六、LINQ缓存依赖实现

1、基础工作:

创建表的触发器,准备表修改记录表,以及二者之间的存储过程。
当然,这些可以直接使用Asp.net提供的这些功能。

2、在DAL层写一个类“DBCacheDependencyDAL.cs”,实现查询[表修改记录表]的功能。

3、在BLL层写一个类“LinQCacheDependencyServer.cs”实现自定义缓存依赖,这个类派生于CacheDependency,并且实现以下的细节:

TableName字段,保存要监视的表名

CurrentId字段,保存缓存创建时changeId字段的值,因为缓存失效时,会重新创建,所以这个属性为只读属性。

DBCallBack(object sender)委托,这个委托会被传递给计时器调用,被调用的时候,它调用CheckTableChanged方法检查表是否已经更新,如果已经更新,那么就会调用基类的NotifyDependencyChanged方法,通知依赖项已经更改。

CheckTableChanged方法:比较CurrentId字段和数据库里的changeId字段,不同则表示已经更新。

4、在添加缓存的时候添加LinQCacheDependency类的实例,作为缓存依赖。

 

◆文档更新说明:

2012年5月3日 17:00 

增加了附件,项目的源代码。

增加了原文的链接。

 

◆附:缓存依赖研究项目源码(包括数据库)

 

◆参数资料:

 

《《解剖PetShop》系列之四 PetShop之ASP.NET缓存》
http://www.cnblogs.com/wayfarer/archive/2006/11/01/547060.html


《系统缓存全解析6:数据库缓存依赖》
http://www.cnblogs.com/ltp/archive/2009/06/30/1514331.html


《ASP.NET 3.5核心编程学习笔记(38):自定义缓存依赖》
http://www.cnblogs.com/free722/archive/2011/04/25/2028780.html

《asp.net 2.0 中使用自定义缓存依赖》
http://www.cnblogs.com/sunwaywei/archive/2006/06/11/423312.html

 


《linq to sql中的自动缓存(对象跟踪)》
http://www.mysjtu.com/page/M0/S438/438073.html

 

《缓存依赖》
http://hi.baidu.com/reallycan/blog/item/89cb5adff9d60c4f95ee3774.html

posted @ 2012-05-03 16:46  柳城之城  阅读(2960)  评论(1编辑  收藏  举报