缓存是用来提高应用性能,降低服务器压力。适用于数据不易变,数据易通用的情景, 对于动态查询数据,例如数据分析,最好放弃使用缓存。使用缓存最麻烦的就是保持源数据和缓存的中的数据一致。

缓存(Cache)依赖,就是缓存是否更新依赖于其它Object。.net的缓存依赖主要用到的类就是CacheDependency、SqlCacheDependency、AggregateCacheDependency。

SqlCacheDependency指的就是Cache的数据更新依赖于SQL Server数据库表的变化( 行级别更改)或者SQL 查询结果的变化。

CacheDependency跟踪缓存依赖项,缓存依赖项可以是应用程序的 Cache 中的文件、目录或与其他对象的键。SqlCacheDependency类在所有受支持的 SQL Server 版本 (7.0, 2000, 2005) 上监视特定的 SQL Server 数据库表,以便在该表发生更改时,自动从 Cache 中删除与该表关联的项。 数据库表发生更改时,将自动删除缓存项,并向 Cache 中添加新版本的项。

AggregateCacheDependency 类监视依赖项对象的集合,以便在任何依赖项对象更改时,该缓存项都会自动移除。数组中的对象可以是CacheDependency 对象、SqlCacheDependency 对象、从 CacheDependency 派生的自定义对象或这些对象的任意组合。

AggregateCacheDependency 类与 CacheDependency 类的不同之处在于前者允许您将不同类型的多个依赖项与单个缓存项关联。例如,如果您创建一个从 SQL Server 数据库表和 XML 文件导入数据的页,则可创建一个 SqlCacheDependency 对象来表示数据库表的依赖项,以及一个 CacheDependency 来表XML 文件的依赖项。可创建 AggregateCacheDependency 类的一个实例,将每个依赖项添加到该类中,而不是为每个依赖项调用 Cache.Insert 方法。然后,可使用单个Insert 调用使该页依赖于 AggregateCacheDependency 实例。

下面就通过一个具体的例子让我们来感受一下在asp.net mvc5中使用缓存依赖和不使用缓存依赖我区别。

一、没有使用缓存依赖的例子

首先,用vs2013创建一个mvc5项目,本文使用nuget安装dapper来访问数据库。

HomeController.cs:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6. using Dapper;
  7. namespace CacheDependency.Controllers
  8. {
  9. publicclassHomeController:Controller
  10. {
  11. publicActionResultIndex()
  12. {
  13. var r=HttpContext.Cache["employees"]asIEnumerable<Models.Employee>;
  14. if(r ==null)
  15. {
  16. using (var conn =newSystem.Data.SqlClient.SqlConnection("Server=.;Database=Test1;uid=sa;pwd=sa"))
  17. {
  18. conn.Open();
  19. r = conn.Query<Models.Employee>("select * from Employee");
  20. conn.Close();
  21. HttpContext.Cache["employees"]= r;
  22. ViewBag.DataFromMsg="数据来源--DB";
  23. returnView(r);
  24. }
  25. }
  26. else
  27. ViewBag.DataFromMsg="数据来源--HttpContext.Cache";
  28. returnView(r);
  29. }
  30. }
  31. }

Index对应的视图:

  1. @modelIEnumerable<CacheDependency.Models.Employee>
  2. @{
  3. ViewBag.Title="Home Page";
  4. }
  5. <h1>@ViewBag.DataFromMsg</h1>
  6. <table>
  7. <tr>
  8. <th>EID</th>
  9. <th>NAME</th>
  10. <th>Age</th>
  11. </tr>
  12. @foreach (var item in Model)
  13. {
  14. <tr>
  15. <td>@item.EID</td>
  16. <td>@item.NAME</td>
  17. <td>@item.Age</td>
  18. </tr>
  19. }
  20. </table>

第一次访问页面:

刷新页面,再次访问页面:

可以看到到当第二次访问页面的时候数据是走的缓存而没有从数据库中再次读数据。我们都知道当数据库中的数据有改动的时候,我们需要把原来缓存的数据清理掉,这要才能重新从数据库把数据读取出来并放到缓存中,这样才能保证显示到页面的数据是最新的。如果不使用缓存依赖,要保持源数据和缓存的中的数据一致,我们就要在后台为Employee表每添加、修改或删除一条数据的时候手动地把缓存删除。

  1. HttpContext.Cache["employees"]=null

这样虽然每次通过程序添加数据时能够删除缓存,但是这也一个问题。如果我们直接打开表Employee添加数据或者直接在查询分析器中insert数据,这时是删除不了缓存的,因为根本没有走我们的有删除缓存的程序。通过使用缓存依赖了,不仅可以决这个保持源数据和缓存的中的数据一致问题,还可以让我们的程序更加简洁,去除掉清缓存相关找代码。

二、使用缓存依赖的例子

2.1、修改HomeController代码

  1. publicActionResultIndex()
  2. {
  3. var r=HttpContext.Cache["employees"]asIEnumerable<Models.Employee>;
  4. if(r ==null)
  5. {
  6. using (var conn =newSystem.Data.SqlClient.SqlConnection("Server=.;Database=Test1;uid=sa;pwd=sa"))
  7. {
  8. conn.Open();
  9. r = conn.Query<Models.Employee>("select * from Employee");
  10. conn.Close();
  11. HttpContext.Cache.Insert("employees", r,newSystem.Web.Caching.SqlCacheDependency("Test1","Employee"));
  12. ViewBag.DataFromMsg="数据来源--DB";
  13. returnView(r);
  14. }
  15. }
  16. else
  17. ViewBag.DataFromMsg="数据来源--HttpContext.Cache";
  18. returnView(r);
  19. }

2.2、修改Web.config

在connectionStrings配置结点下添加加入数据库信息:

  1. <addname="Test1"connectionString="Server=.;Database=Test1;uid=sa;pwd=sa"/>

在<system.web>配置结点下添加缓存依赖的相关配置信息:

  1. <caching>
  2. <sqlCacheDependencyenabled="true">
  3. <databases>
  4. <addname="Test1"pollTime="5000"connectionStringName="Test1"/>
  5. </databases>
  6. </sqlCacheDependency>
  7. </caching>

2.3、启用sql server的数据库的数据缓存依赖功能

找到你的项目中Application_Start事件函数,并在最后加入下面的代码启用数据库的数据缓存依赖功能。

  1. var connectionString =System.Configuration.ConfigurationManager.ConnectionStrings["Test1"].ToString();
  2. //启动数据库的数据缓存依赖功能
  3. SqlCacheDependencyAdmin.EnableNotifications(connectionString);
  4. //启用数据表缓存
  5. SqlCacheDependencyAdmin.EnableTableForNotifications(connectionString,"Employee");

2.4、测试结果

我们打开表Emplyee,为其添加一行数据。如下图:

查看页面效果:

刷新页面,再次访问:

可以看到我们没有手动清理缓存,也使缓存自动刷新了。这就是缓存依赖带来的好处,但是使用缓存依赖也有限制:必须用ASP.Net和SQL Server开发应用,也就是SqlCacheDependency是基于微软的那套体制。

现在我们来看看到底它是如何实现的。

一、表的变化

上图可以看到多了一个表AspNet_SqlCacheTablesForChangeNotification,其表表结构和数据如下图:

二、Employee表触发器

新生成了一个触发器名为Employee_AspNet_SqlCacheNotification_Trigger,其内容如下:

  1. CREATE TRIGGER [dbo].[Employee_AspNet_SqlCacheNotification_Trigger] ON [dbo].[Employee]
  2. FOR INSERT, UPDATE, DELETE AS BEGIN
  3. SET NOCOUNT ON
  4. EXEC dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure N'Employee'
  5. END

上面触发器的作用是当在表Employee做插入、修改、删除操作的时候执行一个名为dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure的存储过程,这个存储过程也是我们开启sql server的缓存依赖自动生成的,总的生成了存储过程如下图:

下面我们打开其中的dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure:

  1. Create PROCEDURE [dbo].[AspNet_SqlCacheUpdateChangeIdStoredProcedure]
  2. @tableName NVARCHAR(450)
  3. AS
  4. BEGIN
  5. UPDATE dbo.AspNet_SqlCacheTablesForChangeNotification WITH (ROWLOCK) SET changeId = changeId +1
  6. WHERE tableName =@tableName
  7. END

三、总结

当sql server启用缓存依赖之后,就会在对应的数据库添加相应的表、触发器和一些存储过程。它是利用触发器来监测表的数据的变化,如果有增、删、改就插入数据到通知表,然后通知订阅这个通知的网站失缓存失效。

asp.net mvc5中使用缓存依赖SqlCacheDependency的更多相关文章

  1. asp.net mvc中应用缓存依赖文件(xml)的一个小demo

    最近项目中加了一个通用模块,就是根据一些特殊的tag,然后根据处理这些tag在同一个视图中加载不同的model(个人觉得此功能无任何意义,只是把不同的代码放在了同一个View中). 我的处理思路是这样 ...

  2. ASP.NET MVC5中的数据注解

    ASP.NET MVC5中Model层开发,使用的数据注解有三个作用: 数据映射(把Model层的类用EntityFramework映射成对应的表) 数据验证(在服务器端和客户端验证数据的有效性) 数 ...

  3. asp.net mvc5中的过滤器重写

    asp.net mvc5中增加了一种过滤器类型叫过滤器重写,这种过滤器类型可以在操作或者控制器上忽略更高层次上设置的过滤器类型,它可以重写五种基本的过滤器接口类型:IAuthenticationFil ...

  4. ASP.NET MVC5中的数据注解(转载)

    ASP.NET MVC5中Model层开发,使用的数据注解有三个作用: 数据映射(把Model层的类用EntityFramework映射成对应的表) 数据验证(在服务器端和客户端验证数据的有效性) 数 ...

  5. cache应用(asp.net 2.0 SQL数据缓存依赖 [SqlCacheDependency ] )

    Asp.net 2.0 提供了一个新的数据缓存功能,就是利用sql server2005 的异步通知功能来实现缓存 1.首先在sqlserver2005 中创建一个test的数据库. 在SQL Ser ...

  6. 我用ASP.NET缓存之SQL数据缓存依赖(SqlCacheDependency)

    [名词解释] 缓存(Cache)依赖,大白话解释就是缓存是否更新依赖于其它Object.那么SqlCacheDependency指的就是Cache的数据更新依赖于SQL Server数据库表的变化(  ...

  7. .Net中的缓存依赖配置

    缓存--能非常好的提高网站的性能. 在訪问量大,但更新较少的站点中使用缓存,能够大大提高执行效率. 在.net中给我们提供了非常好的缓存机制.页面缓存.数据缓存,还有非常好的依赖缓存. 依赖缓存优点就 ...

  8. ASP.NET Core中的缓存[1]:如何在一个ASP.NET Core应用中使用缓存

    .NET Core针对缓存提供了很好的支持 ,我们不仅可以选择将数据缓存在应用进程自身的内存中,还可以采用分布式的形式将缓存数据存储在一个“中心数据库”中.对于分布式缓存,.NET Core提供了针对 ...

  9. 在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView

    背景 在前一篇文章<[初学者指南]在ASP.NET MVC 5中创建GridView>中,我们学习了如何在 ASP.NET MVC 中实现 GridView,类似于 ASP.NET web ...

随机推荐

  1. 第1阶段——u-boot分析之make 100ask24x0_config指令(1)

    本文学习目标:         掌握"make 100ask24x0_config"指令在Makefile和mkconfig文件中是怎么实现配置芯片选型 1.执行make 100a ...

  2. c# 网页打印全流程

    说明:我要实现的就是将数据库中Group表的数据查找出来,替换打印模版中的内容,再将模版文件打印出来 1.准备好要打印的模版group_O_train.html <div class=" ...

  3. Linux无法连接上127.0.0.1,拒绝连接,更新时提示无法下载,无法正常使用apt-get update

    你是否遇到过这种情况,在Linux以apt-get update 时更新的时候无法更新,提示一下内容 p { margin-bottom: 0.25cm; line-height: 120% } 错误 ...

  4. web程序员标准环境之DreamWeaver【…

    Adobe Dreamweaver,简称"DW",中文名称 "梦想编织者",是美国MACROMEDIA公司开发的集网页制作和管理网站于一身的所见即所得网页编辑器 ...

  5. 201521123107 《Java程序设计》第11周学习总结

    第11周作业-多线程 1.本周学习总结 2.书面作业 本次PTA作业题集多线程 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用synchronized修饰方法 ...

  6. 微信小程序中的微信支付js代码和流程详解

    微信支付流程 步骤 (一)获取用户的信息 (二)统一下单(返回的prepay_id用于第(三)步的请求参数) (三)发起支付请求 操作(这边假设你已经获得了用户的openId) (一).获取用户ope ...

  7. 201521123093 java 第八周总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 1.2 选做:收集你认为有用的代码片段 1.泛型简介:同一个代码可以被不同的对象重用 2.使用泛型的好处:允许 ...

  8. 201521123105 第四周Java学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. 继承与多态的概念与实现父类与之类的关系解决代码复用的办法 2. 书面作业 2.1 将在网上商 ...

  9. java201521123118《java程序设计》第3周总结

    1. 本周学习 总结初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识组织起来.请使用纸笔或者下面的工具画出本周学习到的知识点.截图或者拍照上传. 2. 书面作 ...

  10. Markdown例子

    一个例子: 例子开始 1. 本章学习总结 今天主要学习了三个知识点 封装 继承 多态 2. 书面作业 Q1. java HelloWorld命令中,HelloWorld这个参数是什么含义? 今天学了一 ...