PetShop之ASP.NET缓存

固然说编程方式给予了程序员更大的油滑,但aspnet_regsql工具却提供了更简约的法子完毕对SqlCacheDependency的布局与管理。PetShop
4.0利用的难为aspnet_regsql工具的法门,它编写了一个文件名为InstallDatabases.cmd的批处理公事,其中蕴藏了对aspnet_regsql工具的执行,并经过安装程序去调用该公文,完成对SQL
Server的陈设。

    private static readonly int productTimeout =
int.Parse(ConfigurationManager.AppSettings[“ProductCacheDuration”]);
    private static readonly bool enableCaching =
bool.Parse(ConfigurationManager.AppSettings[“EnableCaching”]);
       
    public static IList
GetProductsByCategory(string category)
    {
        Product product = new Product();

4.3.3  CacheDependency工厂

动用Facade格局可以将一部分扑朔迷离的逻辑进行打包,以方便调用者对那一个复杂逻辑的调用。就就好像提供一个集合的假相一般,将里面的子系统封装起来,统一为一个高层次的接口。一个良好的Facade情势示意图如下所示:

在PetShop
4.0的命名空间PetShop.ICacheDependency中,定义了名为IPetShopCacheDependency接口,它仅包涵了一个接口方法:
public interface IPetShopCacheDependency
{      
    AggregateCacheDependency GetDependency();
}

SqlCacheDependency特性实际上是通过System.Web.Caching.SqlCacheDependency类来突显的。通过此类,能够在颇具帮助的SQL
Server版本(7.0,2000,2005)上监视特定的SQL
Server数据库表,并创设器重于该表以及表中数据行的缓存项。当数据表或表中特定行的多少发生变更时,具有依赖项的多寡项就会失灵,并自行从Cache中删去该项,从而保险了缓存中不再保留过期的数目。
由于版本的来由,SQL Server 2005一心扶助SqlCacheDependency特性,但对于SQL
Server 7.0和SQL Server
2000而言,就从来不如此幸运了。毕竟这么些产品出现在.Net Framework
2.0以前,由此它并从未落到实处活动监视数据表数据变动,文告ASP.NET的功力。解决的点子就是利用轮询机制,通过ASP.NET进程内的一个线程以指定的时光距离轮询SQL
Server数据库,以跟踪数据的更动处境。

咱俩还足以为应用程序缓存添加信赖项,使得看重项暴发变更时,该数额项可以从缓存中移除:
string[] dependencies = {“Second”};
Cache.Insert(“Third”, “Third Item”,
new System.Web.Caching.CacheDependency(null, dependencies));

在PetShop
4.0的规划中,是透过引入Facade格局以福利调用者尤其简明地得到AggregateCacheDependency类型对象。

若是大家定义了如下的数据库连接字符串:
const string connectionStr = “Server=localhost;Database=MSPetShop4”;

4.3.1  CacheDependency接口

4.3.5  引入Proxy模式

但是如此的做法纷扰了作为工厂类的DependencyAccess的自我任务,且创造IPetShopCacheDependency接口对象的一颦一笑依旧有可能被调用者调用,所以保留原有的DependencyAccess类仍然是有须要的。

Facade形式的目的决不要引入一个新的功力,而是在存活功效的底蕴上提供一个更高层次的空洞,使得调用者可以间接调用,而不用关爱内部的落实格局。以CacheDependency工厂为例,大家必要为调用者提供获得AggregateCacheDependency对象的便民方法,因此创立了DependencyFacade类:
public static class DependencyFacade
{
    private static readonly string path =
ConfigurationManager.AppSettings[“CacheDependencyAssembly”];
    public static AggregateCacheDependency GetCategoryDependency()
    {
        if (!string.IsNullOrEmpty(path))
            return
DependencyAccess.CreateCategoryDependency().GetDependency();
        else
            return null;
    }
    public static AggregateCacheDependency GetProductDependency()
    {
        if (!string.IsNullOrEmpty(path))
            return
DependencyAccess.CreateProductDependency().GetDependency();
        else
            return null;
        }
    public static AggregateCacheDependency GetItemDependency()
    {
        if (!string.IsNullOrEmpty(path))
            return
DependencyAccess.CreateItemDependency().GetDependency();
        else
            return null;
    }
}

productsList对象属于自定义的CustomList类型,那是一个派生自System.Web.UI.WebControls.DataList控件的类,它的DataSource属性可以承受IList集合对象。
不过在PetShop
4.0的安排中,对于接近于ProductsControl类型的控件而言,接纳的缓存机制是页输出缓存。大家得以从ProductsControl.ascx页面的Source代码中发觉端倪:
<%@ OutputCache Duration=”100000″ VaryByParam=”page;categoryId” %>

以PetShop.BLL.Product业务对象为例,PetShop为其树立了代办对象ProductDataProxy,并在GetProductByCategory()等办法中,引入了缓存机制,例如:
public static class ProductDataProxy
{

4.1  ASP.NET缓存概述

引入缓存看来是增高品质的“完美”解决方案,可是“金无足赤,人无完人”,缓存机制也有缺点,那就是数据过期的标题。一旦应用程序数据照旧页面结果值暴发的改观,那么在缓存有效期范围内,你所得到的结果将是逾期的、不规范的多寡。大家得以想一想股票系统使用缓存所牵动的魔难,当您利用错误过期的数目去分析股市的风云万变时,你会发觉赢得的结果真可以说是“失之毫厘,谬以千里”,看似大好的层面就会像美观的泡沫一样,用针一戳,转眼就消灭得无影无踪。

如此一来,ASP.NET会对txtCity控件的值举办判断,唯有输入的值与缓存值相同,才从缓存中取出相应的值。那就有效地防止了因为值的不比而造成出口错误的数额。

4.3.2  CacheDependency实现

AggregateCacheDependency是.Net Framework
2.0新增的一个类,它负责监视器重项对象的会师。当那个集合中的任意一个凭借项对象发生改变时,该正视项对象对应的缓存对象都将被电动移除。
AggregateCacheDependency类起到了整合CacheDependency对象的功能,它可以将八个CacheDependency对象竟然分歧品种的CacheDependency对象与缓存项建立关系。由于PetShop必要为Category、Product和Item数据表建立看重项,由此IPetShopCacheDependency的接口方法GetDependency()其目的就是再次回到建立了那几个信赖项的AggregateCacheDependency对象。

在PetShop
4.0中,依旧拔取了配备文件和反光技术来促成工厂形式。命名空间PetShop.CacheDependencyFactory中,类DependencyAccess即为创制IPetShopCacheDependency对象的工厂类:
public static class DependencyAccess
{       
    public static IPetShopCacheDependency CreateCategoryDependency()
    {
        return LoadInstance(“Category”);
    }
    public static IPetShopCacheDependency CreateProductDependency()
    {
        return LoadInstance(“Product”);
    }
    public static IPetShopCacheDependency CreateItemDependency()
    {
        return LoadInstance(“Item”);
    }
    private static IPetShopCacheDependency LoadInstance(string
className)
    {
        string path =
ConfigurationManager.AppSettings[“CacheDependencyAssembly”];
        string fullyQualifiedClass = path + “.” + className;
        return
(IPetShopCacheDependency)Assembly.Load(path).CreateInstance(fullyQualifiedClass);
    }
}
总体工厂形式的落实如图4-3所示:

即使DependencyAccess类创造了落实了IPetShopCacheDependency接口的类Category、Product、Item,然而我们所以引入IPetShopCacheDependency接口,其目标就在于获取创造了借助项的AggregateCacheDependency类型的靶子。我们得以调用对象的接口方法GetDependency(),如下所示:
AggregateCacheDependency dependency =
DependencyAccess.CreateCategoryDependency().GetDependency();

ASP.NET提供了三种为主的缓存机制来提供缓存成效。一种是应用程序缓存,它同意开发者将先后生成的数码或报表工作对象放入缓存中。其它一种缓存机制是页输出缓存,利用它,可以直接获取存放在缓存中的页面,而不需求通过繁杂的对该页面的再次拍卖。

为了便利调用者,就像是大家得以对DependencyAccess类举行改进,将原来的CreateCategoryDependency()方法,修改为创立AggregateCacheDependency类型对象的法子。

页输出缓存分为整页缓存和局地页缓存。大家得以经过@OutputCache指令完成对Web页面的输出缓存。它最主要包括多少个参数:Duration和VaryByParam。Duration参数用于安装页面或控件举办缓存的岁月,其单位为秒。如下的安装表示缓存在60秒内有效:
<%@ OutputCache Duration=“60“ VaryByParam=“none“ %>

要使得7.0要么2000版本的SQL
Server襄助SqlCacheDependency特性,须求对数据库服务器执行有关的配备步骤。有几种方法配置SQL
Server:使用aspnet_regsql命令行工具,或者利用SqlCacheDependencyAdmin类。

    protected AggregateCacheDependency dependency = new
AggregateCacheDependency();
    protected TableDependency(string configKey)
    {
        string dbName =
ConfigurationManager.AppSettings[“CacheDatabaseName”];
        string tableConfig =
ConfigurationManager.AppSettings[configKey];
        string[] tables = tableConfig.Split(configurationSeparator);

DisableNotifications 为特定数据库禁用 SqlCacheDependency对象更改通知
DisableTableForNotifications 为数据库中的特定表禁用SqlCacheDependency对象更改通知
EnableNotifications 为特定数据库启用SqlCacheDependency对象更改通知
EnableTableForNotifications 为数据库中的特定表启用SqlCacheDependency对象更改通知
GetTablesEnabledForNotifications 返回启用了SqlCacheDependency对象更改通知的所有表的列表

            // Create a AggregateCacheDependency object from the
factory
            AggregateCacheDependency cd =
DependencyFacade.GetProductDependency();

假若须要对UI层采取缓存机制,将应用程序数据存放到缓存中,就能够调用那些代理对象。以ProductsControl用户控件为例,调用形式如下:
productsList.DataSource =
ProductDataProxy.GetProductsByCategory(categoryKey);

以下是该工具的下令参数表达:
-?  突显该工具的声援意义;
-S  后接的参数为数据库服务器的称呼或者IP地址;
-U  后接的参数为数据库的登陆用户名;
-P  后接的参数为数据库的登陆密码;
-E  当使用windows集成验证时,使用该意义;
-d  后接参数为对哪一个数据库采纳SqlCacheDependency功用;
-t  后接参数为对哪一个表采取SqlCacheDependency功效;
-ed  允许对数据库使用SqlCacheDependency成效;
-dd  禁止对数据库选取SqlCacheDependency功用;
-et  允许对数据表拔取SqlCacheDependency功效;
-dt  禁止对数据表选拔SqlCacheDependency作用;
-lt  列出如今数据库中有怎么样表已经应用sqlcachedependency效用。

依照种种数据表间的看重性关系,因此分裂的数据表需求树立的依靠项也是不等同的,从配置文件中的value值可以见见。不过不管建立重视项的数量,其创立的一坐一起逻辑都是一般的,由此在设计时,抽象了一个联机的类TableDependency,并经过创制带参数的构造函数,落成对重视项的树立。由于接口方法GetDependency()的落实中,重回的对象dependency是在受有限支持的构造函数创设的,由此那里的兑现格局也足以用作是Template
Method格局的灵活运用。例如TableDependency的子类Product,就是选择父类的构造函数建立了Product、Category数据表的SqlCacheDependency珍贵:
public class Product : TableDependency
{
    public Product() : base(“ProductTableDependency”) { }
}

假定对微型电脑硬件系统有丰裕的刺探,那么大家对此Cache那一个名词一定是轻车熟路的。在CPU以及主板的芯片中,都引入了那种名为高速缓冲存储器(Cache)的技术。因为Cache的存取速度比内存快,因此引入Cache能够有效的缓解CPU与内存之间的进程不兼容难题。硬件系统可以运用Cache存储CPU访问概率高的那个数据,当CPU要求拜访这么些数据时,可以直接从Cache中读取,而不必访问存取速度相对较慢的内存,从而升高了CPU的工作功效。软件设计借鉴了硬件设计中引入缓存的建制以改正整个系统的品质,尤其是对此一个数据库驱动的Web应用程序而言,缓存的施用是须求的,毕竟,数据库查询可能是任何Web站点中调用最频仍但同时又是履行最缓慢的操作之一,大家无法被它老迈的双腿拖缓大家进步的征途。缓存机制正是解决这一欠缺的加快器。

当执行上述的四条命令后,aspnet_regsql工具会在MSPetShop4数据库中创设一个名为AspNet_SqlCacheTablesForChangeNotification的新数据库表。该数据表包含多个字段。字段tableName记录要追踪的数据表的名号,例如在PetShop
4.0中,要记录的数据表就概括Category、Item和Product。notificationCreated字段记录开始追踪的时辰。changeId作为一个类型为int的字段,用于记录数据表数据爆发变化的次数。如图4-2所示:

为数量表Product启用SqlCacheDependency对象更改文告的完毕则为:
SqlCacheDependencyAdmin.EnableTableForNotifications(connectionStr,
“Product”);

此起彼伏了抽象类TableDependency的Product、Category和Item类均须要在调用时创制各自的目的。由于它们的父类TableDependency完毕了接口IPetShopCacheDependency,因此它们也直接落成了IPetShopCacheDependency接口,那为贯彻工厂方式提供了前提。

        foreach (string tableName in tables)
            dependency.Add(new SqlCacheDependency(dbName, tableName));
    }
    public AggregateCacheDependency GetDependency()
   {
        return dependency;
    }
}

从任务分开与分支设计的角度解析,我更希望这几个Proxy对象是被定义在作业逻辑层中,而不像在PetShop的安排那样,被分割到代表层UI中。别的,如若急需考虑程序的可增加性与可替换性,我们还足以为实际对象与代理对象建立统一的接口或抽象类。然则,单以PetShop的表示层调用来看,拔取静态类与静态方法的措施,或许越发客观。大家须求谨记,“过度设计”是软件设计的警戒线。

     string cacheKey = string.Format(CATEGORY_NAME_KEY, categoryId);

内需建立依赖项的数据库与数码表都配置在web.config文件中,其设置如下:
<add key=”CacheDatabaseName” value=”MSPetShop4″/>
<add key=”CategoryTableDependency” value=”Category”/>
<add key=”ProductTableDependency” value=”Product,Category”/>
<add key=”ItemTableDependency” value=”Product,Category,Item”/>

        if (!enableCaching)
            return product.GetProductsByCategory(category);

PetShop作为一个B2C的宠物网上商店,须要足够考虑访客的用户体验,即使因为数据量大而致使Web服务器的响应不及时,页面和询问数据迟迟得不到结果,会由此而破坏客户走访网站的心境,在耗尽耐心的等待后,可能会失去这一有的客户。无疑,这是卓殊不佳的结果。因此在对其开展系统架构设计时,整个种类的性质就显得殊为紧要。不过,咱们不能付之东流,因为在意于品质而忽视数据的不错。在PetShop
3.0本子以及之前的本子,因为ASP.NET缓存的局限性,这一题材并不曾到手很好的化解。PetShop
4.0则引入了SqlCacheDependency特性,使得系统对缓存的处理相比较往日大为改观。

.Net 2.0引入的自定义缓存依赖项,越发是基于MS-SQL
Server的SqlCacheDependency特性,使得大家可以幸免“数据过期”的标题,它亦可依照数据库中相应数额的变迁,布告缓存,并移除那个过期的多寡。事实上,在PetShop
4.0中,就丰硕地应用了SqlCacheDependency特性。

4.2.2  利用SqlCacheDependencyAdmin类

PetShop
4.0引入了SqlCacheDependency特性,对Category、Product和Item数据表对应的缓存举行了SQL
Cache
Invalidation技术。当对应的数据表数据暴发转移后,该技能可以将相关项从缓存中移除。已毕这一技能的为主是SqlCacheDependency类,它继续了CacheDependency类。然则为了保险一切架构的可伸张性,大家也允许设计者建立自定义的CacheDependency类,用以扩大缓存看重。那就有要求为CacheDependency建立抽象接口,并在web.config文件中展开陈设。

与ASP.NET 1.x的页输出缓存分化的是,在ASP.NET
2.0中,为ASP.NET用户控件新引入了CachePolicy属性,该属性的花色为ControlCachePolicy类,它以编程格局贯彻了对ASP.NET用户控件的输出缓存设置。大家得以经过设置ControlCachePolicy类的Dependency属性,来安装与该用户控件相关的依靠项,例如在ProductsControl用户控件中,举行如下的装置:
protected void Page_Load(object sender, EventArgs e)
{
    this.CachePolicy.Dependency =
DependencyFacade.GetProductDependency();
}

比起平素调用DependencyAccess类的GetDependency()方法而言,除了艺术更简明之外,同时它还对CacheDependencyAssembly配置节进行了判断,借使其值为空,则赶回null对象。

即使要调用表4-1中所示的相关措施,须求留意的是访问SQL
Server数据库的帐户必须拥有创造表和仓储进程的权柄。若是要调用EnableTableForNotifications方法,还亟需具有在该表上创制SQL
Server触发器的权位。

     // 检查缓存中是或不是留存该数额项;
     string data = (string)HttpRuntime.Cache[cacheKey];
     if (data == null)
     {
           // 通过web.config的配置获取duration值;
           int cacheDuration =
int.Parse(ConfigurationManager.AppSettings[“CategoryCacheDuration”]);
           //
如若缓存中不存在该数据项,则经过作业逻辑层访问数据库获取;
           data = category.GetCategory(categoryId).Name;
           // 通过Facade类创建AggregateCacheDependency对象;
           AggregateCacheDependency cd =
DependencyFacade.GetCategoryDependency();
           // 将数据项以及AggregateCacheDependency 对象存储到缓存中;
           HttpRuntime.Cache.Add(cacheKey, data, cd,
DateTime.Now.AddHours(cacheDuration), Cache.NoSlidingExpiration,
CacheItemPriority.High, null);
      }
      return data;
}

图片 1
图4-2 AspNet_SqlCacheTablesForChangeNotification数据表

GetCategoryName()方法首先会检讨缓存中是还是不是已经存在CategoryName数据项,若是已经存在,就透过缓存直接获取数据;否则将由此作业逻辑层调用数据访问层访问数据库得到CategoryName,在赢得了CategoryName后,会将新取得的数据及其DependencyFacade类创立的AggregateCacheDependency对象添加到缓存中。

其中,AspNet_SqlCacheUpdateChangeIdStoredProcedure即是工具添加的一组存储进度中的一个。当对Product数据表执行Insert、Update或Delete等操作时,就会激活触发器,然后实施AspNet_SqlCacheUpdateChangeIdStoredProcedure存储进度。其实施的进度就是修改AspNet_SqlCacheTablesForChangeNotification数据表的changeId字段值:
CREATE PROCEDURE dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure
             @tableName NVARCHAR(450)
         AS
         BEGIN
             UPDATE dbo.AspNet_SqlCacheTablesForChangeNotification WITH
(ROWLOCK) SET changeId = changeId + 1
             WHERE tableName = @tableName
         END  
GO

CacheDependency的落到实处正是为Category、Product和Item数据表建立了相应的SqlCacheDependency类型的信赖项,如代码所示:
public abstract class TableDependency : IPetShopCacheDependency
{
    // This is the separator that’s used in web.config
    protected char[] configurationSeparator = new char[] { ‘,’ };

那么我们是还是不是相应为了追求高质量,而不顾所谓“数据过期”所推动的隐患呢?鲜明,在相近于股票系统那种数据更新往往的一定情景下,数据过期的不得了表现甚至比低效的性质更令人难以承受。故而,大家要求在性质与数量正确性间作出权衡。所幸的是,.Net
Framework
2.0引入了一种新的缓存机制,它为我们的“鱼与熊掌兼得”带来了技术上的主旋律。

与事务逻辑层Product对象的GetProductsByCategory()方法比较,增添了缓存机制。当缓存内不存在相关数据项时,则一贯调用业务逻辑层Product的GetProductsByCategory()方法来获取数据,并将其与相应的AggregateCacheDependency对象一起存储在缓存中。

应用缓存的建制对品质的升级格外明确。通过ACT(Application Center
Test)的测试,能够窥见安装缓存后执行的质量比未安装缓存时的质量足足增强三倍多。

应用程序缓存其落到实处原理说来平淡无奇,仅仅是因此ASP.NET管理内存中的缓存空间。放入缓存中的应用程序数据对象,以键/值对的不二法门存储,那便于用户在走访缓存中的数据项时,可以根据key值判断该项是或不是留存缓存中。

在.Net
Framework中,应用程序缓存通过System.Web.Caching.Cache类已毕。它是一个密封类,无法被持续。对于每一个选取程序域,都要开创一个Cache类的实例,其生命周期与行使程序域的生命周期保持一致。咱们可以利用Add或Insert方法,将数据项添加到应用程序缓存中,如下所示:
Cache[“First”] = “First Item”;
Cache.Insert(“Second”, “Second Item”);

aspnet_regsql工具位于Windows\Microsoft.NET\Framework\[版本]文本夹中。借使直接双击该工具的实践文书,会弹出一个指路对话框,提醒大家完结相应的操作:

4.3.4  引入Facade模式

那么为数据库MSPetShop4启用SqlCacheDependency对象更改公告的落到实处为:
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
   {
       SqlCacheDependencyAdmin.EnableNotifications(connectionStr);
   }
}

借使没有当先Duration设置的限期值,当用户访问同一的页面或控件时,就足以一贯在缓存中赢得。
应用VaryByParam参数可以按照设置的参数值建立分歧的缓存。例如在一个出口天气预先报告结果的页面中,假如要求为一个ID为txtCity的TextBox控件建立缓存,其值将浮现某都会的天气温度,那么大家能够展开如下的装置:
<%@ OutputCache Duration=”60” VaryByParam=”txtCity” %>

如图4-1所示中的提醒信息,表达该引路首要用于配置SQL
Server数据库,如membership,profiles等信息,假如要布局SqlCacheDependency,则须求以命令行的主意实施。以PetShop
4.0为例,数据库名为MSPetShop4,则下令为:
aspnet_regsql -S localhost -E -d MSPetShop4 -ed

        // Check if the data exists in the data cache
        if (data == null)
        {
            data = product.GetProductsByCategory(category);

        string key = “product_by_category_” + category;
        IList data = (IList )HttpRuntime.Cache[key];

来得页面title的逻辑是坐落Page_Load事件措施中,因此每趟打开该页面都要实践获取CategoryName的办法。如果没有应用缓存机制,当Category数据较多时,页面的来得就会更加缓慢。

4.2 SqlCacheDependency特性

WebUtility静态类被表示层的成百上千页面所调用,例如Product页面:
public partial class Products : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Page.Title =
WebUtility.GetCategoryName(Request.QueryString[“categoryId”]);
    }
}

与之对应的是缓存中多少项的移除。前面提到ASP.NET可以自行管理缓存中项的移除,但大家也可以通过代码编写的主意显式的移除相关的数码项:
Cache.Remove(“First”);

在PetShop.Web的App_Code文件夹下,静态类WebUtility的GetCategoryName()和GetProductName()方法调用了DependencyFacade类。例如GetCategoryName()方法:
public static string GetCategoryName(string categoryId)
{
     Category category = new Category();
     if (!enableCaching)
            return category.GetCategory(categoryId).Name;

图片 2
图4-1 aspnet_regsql工具

使用页输出缓存,并且应用ControlCachePolicy设置输出缓存,可以将事情数据与成套页面放入到缓存中。那种艺术比起应用程序缓存而言,在性质上有很大的增高。同时,它又经过引入的SqlCacheDependency特性有效地防止了“数据过期”的通病,由此在PetShop
4.0中被普遍利用。相反,此前为Product、Category、Item业务对象建立的代理对象则被“投闲散置”,仅仅作为一种设计方式的浮现而“幸存”与一切系统的源代码中。

四 PetShop之ASP.NET缓存

《解剖PetShop》种类之四

作为.Net框架下开发Web应用程序的主打产品,ASP.NET丰盛考虑了缓存机制。通过某种方式,将系统必要的数量对象、Web页面存储在内存中,使得Web站点在需求取得那几个多少时,不要求经过繁琐的数据库连接、查询和复杂性的逻辑运算,就足以“触手可及”,如“毫不费力”般简单而急速,从而提升总体Web系统的性质。

以地点的授命为例,表达将对名为MSPetShop4的数据库选用SqlCacheDependency作用,且SQL
Server拔取了windows集成验证办法。大家还足以对有关的数据表执行aspnet_regsql命令,如:
aspnet_regsql -S localhost -E -d MSPetShop4 -t Item -et
aspnet_regsql -S localhost -E -d MSPetShop4 -t Product -et
aspnet_regsql -S localhost -E -d MSPetShop4 -t Category -et

            // Store the output in the data cache, and Add the necessary
AggregateCacheDependency object
            HttpRuntime.Cache.Add(key, data, cd,
DateTime.Now.AddHours(productTimeout), Cache.NoSlidingExpiration,
CacheItemPriority.High, null);
        }
        return data;
    }
}

放入在缓存中的数据对象其生命周期是饱受限制的,就算在任何应用程序的生命周期里,也不可以担保该数额对象一贯有效。ASP.NET可以对应用程序缓存进行管制,例如当数码项无效、过期或内存不足时移除它们。别的,调用者仍能够通过CacheItemRemovedCallback委托,定义回调方法使得数据项被移除时可以通告用户。

4.3 在PetShop 4.0中ASP.NET缓存的贯彻

DependencyFacade类封装了获得AggregateCacheDependency类型对象的逻辑,如此一来,调用者可以调用相关办法获得创建连锁器重项的AggregateCacheDependency类型对象:
AggregateCacheDependency dependency =
DependencyFacade.GetCategoryDependency();

俺们也足以动用编程的法子来来管理数据库对SqlCacheDependency特性的采用。该类包罗了多个重点的点子:

图片 3
图4-4 Facade模式

相对于应用程序缓存而言,页输出缓存的应用越来越广阔。它可以透过内存将处理后的ASP.NET页面存储起来,当客户端再一遍访问该页面时,可以节约页面处理的经过,从而进步页面访问的属性,以及Web服务器的吞吐量。例如,在一个电子商务网站里,用户必要平时查询商品音信,那些历程会波及到数据库访问以及查找条件的同盟,在数据量较大的动静下,如此的物色进程是较为耗时的。此时,利用页输出缓存就足以将率先次搜索得到的查询结果页存储在缓存中。当用户第二次询问时,就足以节约数据查询的历程,裁减页面的响应时间。

假若急需自定义CacheDependency,那么创建器重项的法子又有差异。可是不管是创造SqlCacheDependency对象,如故自定义的CacheDependency对象,都是将这么些依赖项添加到AggregateCacheDependency类中,由此大家也得以为自定义CacheDependency建立专门的类,只要完成IPetShopCacheDependency接口即可。

表4-1 SqlCacheDependencyAdmin类的根本方法

图片 4
 图4-3 CacheDependency工厂

4.2.1  利用aspnet_regsql工具

业务逻辑层BLL中与Product、Category、Item有关的事体方法,其落实逻辑是调用数据访问层(DAL)对象访问数据库,以取得相关数据。为了句酌字斟系统质量,大家就要求为这一个落成格局增添缓存机制的逻辑。当大家操作增添了缓存机制的事情对象时,对于调用者而言,应与BLL业务对象的调用保持一致。也即是说,大家要求引入一个新的目的去控制原来的BLL业务对象,那几个新的靶子就是Proxy形式中的代理对象。

除去,执行该命令还会为MSPetShop4数据库添加一组存储进度,为ASP.NET提供查询追踪的数据表的事态,同时还将为利用了SqlCacheDependency的表添加触发器,分别对应Insert、Update、Delete等与数码变动相关的操作。例如Product数据表的触发器:
CREATE TRIGGER dbo.[Product_AspNet_SqlCacheNotification_Trigger] ON
[Product]
    FOR INSERT, UPDATE, DELETE AS BEGIN
    SET NOCOUNT ON
    EXEC dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure N’Product’
END

引入Proxy形式,完成了在缓存级别上对工作对象的包裹,增强了对作业对象的支配。由于揭破在对象外的措施是同一的,因此对于调用方而言,调用代理对象与忠实对象并不曾精神的区分。

相关文章