热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

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


导读:

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

 

一、缘起

(本文发布于博客园,作者在博客园的博客地址是: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控件插入数据。

 

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

实验的现象一:

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

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

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


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

实验的现象二:

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


进一步结论:

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


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

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

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当中使用缓存依赖


六、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


推荐阅读
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • 本文介绍了在使用Laravel和sqlsrv连接到SQL Server 2016时,如何在插入查询中使用输出子句,并返回所需的值。同时讨论了使用CreatedOn字段返回最近创建的行的解决方法以及使用Eloquent模型创建后,值正确插入数据库但没有返回uniqueidentifier字段的问题。最后给出了一个示例代码。 ... [详细]
author-avatar
海角处回忆_417
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有