Robin's Blog

记录 积累 学习 成长

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Asp.net 2.0 提供了一个新的数据缓存功能,就是利用sql server2005 的异步通知功能来实现缓存

1.首先在sqlserver2005 中创建一个test的数据库.

      在SQL Server 2005上执行

             ALTER DATABASE <DatabaseName> SET ENABLE_BROKER;语句让相应的数据库启用监听服务,以便支持SqlDependency特性。

 

添加一个 employee的数据库表.

 

1CREATE TABLE [dbo].[employee](
2    [id] [int] IDENTITY(1,1NOT NULL
,
3    [name] [varchar](50

4

5



2使用 vs2005 创建一个新的asp.net项目.

web.config如下

 1<?xml version="1.0"?>
 2<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
 3    <appSettings/>
 4    <connectionStrings>
 5        <add name="mySource" connectionString="Data Source=.\sql2005;Initial Catalog=test;Persist Security Info=True;User ID=sa;Password=sasa" providerName="System.Data.SqlClient"></add>
 6    </connectionStrings>
 7    <system.web>
 8        <compilation debug="true"/>
 9        <authentication mode="Windows"/>
10    </system.web>
11</configuration>
12

3.编写global.asax文件,启动监听sql2005通知事件.

<%@ Application Language="C#" %>
<%@ Import Namespace="System.Data.SqlClient" %>

<script runat="server">

    
void Application_Start(object sender, EventArgs e) 
    
{
        
string connStr=ConfigurationManager.ConnectionStrings["mySource"
].ConnectionString;
        SqlDependency.Start(connStr);
    }

    
    
void Application_End(object sender, EventArgs e) 
    
{
        
string connStr = ConfigurationManager.ConnectionStrings["mySource"
].ConnectionString;
        SqlDependency.Stop(connStr);
    }

</script>

4.编写数据访问代码.创建一个EmployeeData的类,代码如下

using System;
using
 System.Data;
using
 System.Data.SqlClient;
using
 System.Configuration;
using
 System.Data.Common;
using
 System.Web;
using
 System.Web.Caching;
using
 System.Web.Security;
using
 System.Web.UI;
using
 System.Web.UI.WebControls;
using
 System.Web.UI.WebControls.WebParts;
using
 System.Web.UI.HtmlControls;

/// <summary>
/// EmployeeData 的摘要说明
/// </summary>

public class EmployeeData
{
    
public
 EmployeeData()
    
{
    }


    
private HttpContext context;

    
public
 DataSet GetCacheData()
    
{
        context 
=
 HttpContext.Current;
        DataSet cache 
=(DataSet) context.Cache["employee"
];
        
if (cache == null
)
        
{
            
return
 GetData();
        }

        
else
        
{
            
return
 cache;
        }

    }



    
public DataSet GetData()
    
{
        
string connStr = ConfigurationManager.ConnectionStrings["mySource"
].ConnectionString;
        SqlConnection conn 
= new
 SqlConnection(connStr);
        SqlDataAdapter adp 
= new SqlDataAdapter("select id,name from dbo.employee"
, conn);
        SqlCacheDependency dep 
= new
 SqlCacheDependency(adp.SelectCommand);
        DataSet ds
=new
 DataSet();
        adp.Fill(ds);
        context.Cache.Add(
"employee", ds, dep, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, new CacheItemRemovedCallback(this
.DataDiff));
        
return
 ds;
    }


    
public void DataDiff(string key, object value, CacheItemRemovedReason reason)
    
{
        Console.WriteLine(
"key:" +
 key);
        GetData();
    }


}

这里需要注意的是 select语句的写法, 不能使用 select *  的方式,一定要在表名前加架构名称 如我们这里的 dbo.employee.

5.编写测试页面代码.

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title>无标题页</title>
</head>
<body>
    
<form id="form1" runat="server">
    
<div>
        
<asp:GridView ID="GridView1" runat="server" >
        
</asp:GridView>
    
</div>
    
</form>
</body>
</html>

6.插入后台代码

using System;
using
 System.Data;
using
 System.Configuration;
using
 System.Web.Caching;
using
 System.Data.SqlClient;
using
 System.Web;
using
 System.Web.Security;
using
 System.Web.UI;
using
 System.Web.UI.WebControls;
using
 System.Web.UI.WebControls.WebParts;
using
 System.Web.UI.HtmlControls;

public partial class
 _Default : System.Web.UI.Page 
{
    
protected void Page_Load(object
 sender, EventArgs e)
    
{
        EmployeeData em
=new
 EmployeeData();
        GridView1.DataSource 
=
 em.GetCacheData();
        GridView1.DataBind();
    }


 

 

SQL数据缓存依赖 [SqlServer | Cache | SqlCacheDependency ]

支持数据库

     SQL SERVER 7.0/2000/2005版本 

正文

     一、SQL SERVER 7.0/2000和SQL SERVER 2005的简介及比较

          1.1     SQL SERVER 7.0/2000

                   SQL SERVER 7.0/2000没有提供内置的支持数据缓存依赖的功能,所以只能通过采用添加特定数据库表、触发器等方式,通过后台不断轮询数据库来检查数据更改。当在数据表上执行INSERT、UPDATE、 DELETE操作时将自动发出更改通知,所以只能监测到表级,具体到哪一行是没法跟踪的。

                    使用方法步骤:

                    1.1.1     使用aspnet_regsql命令行或SqlCacheDependencyAdmin来配置连接数据库。

                         1.1.1.1     ALTER DATABASE <DatabaseName> SET ENABLE_BROKER;    

                              aspnet_regsql -S <server> -U sa -P sa -d <database> -ed     启动数据库的数据缓存依赖功能

                              aspnet_regsql -S <server> -U sa -P sa -d <database> -t <table> -et     启动数据表的数据缓存依赖功能

                         1.1.1.2

                              SqlCacheDependencyAdmin.EnableNotifications(connectionString);     //启动数据库的数据缓存依赖功能                    

                              SqlCacheDependencyAdmin.EnableTableForNotifications(connectionStringtable);        //启用数据表缓存

                              推荐这段代码写在Global.asaxApplication_Start方法中,以便应用程序启动的时候就启用数据库和数据表的缓存依赖功能。

                    1.1.2     配置Web.config

                         <sqlCacheDependency enabled="true" pollTime="10000">配置在<sytem.web>下的<caching>结点下,只有一个数据库的话不必指定下一级<database>结点

                    1.1.3     应用程序数据缓存中使用(还可以在数据源控件、输出缓存整个页面时使用,这里就不介绍了,下同)

                         SqlCacheDependency scd = new SqlCacheDependency("数据库名称","表名");                         

                         Cache.Insert(...,scd,...);    

          1.2     SQL SERVER 2005

                    内置支持SQL数据缓存依赖,内置通知传递服务,能够提供更小粒度的数据更改监测,使用和配置简单。

                    使用方法步骤:

                    1.2.1     检测是否已经启用Service Broker

                         Select DATABASEpRoPERTYEX('数据库名称','IsBrokerEnabled')          -- 1 表示已经启用 0 表示没有启用

                         这个地方我看有些朋友翻译的成“是否能启用”,这是不对的,这里我把英文原文帖出来:“This can be checked by calling "Select databasepropertyex('db Name', 'IsBrokerEnabled')".  A '1' means that the broker is enabled.  A '0' means that the broker is not enabled.    ”。        

                         依据我的经验,如果直接在当前SqlServer2005上新建一个数据库的话,默认是打开的,如果是从其他地方数据库导过来的,导入之后默认关闭了。(可能有不准确,大家可以自己试验一下测试一下)。如果已经打开可直接调到1.2.2。

                         1.2.1.1     启用Service Broker                    

                              ALTER DATABASE 数据库名称 SET ENABLE_BROKER;                              

                    1.2.2     在实现基于服务的SQL数据缓存依赖过程中,需要显式调用SqlDependency.Start来启动接受依赖项更改通知的侦听器。

                              SqlDependency.Start(connectionString);                         //推荐将这段代码加到Global.asaxApplication_Start方法中,

                              SqlDependency.Stop(connectionString);                         //用于关闭,可加在Global.asaxApplication_End方法中。

                    1.2.3     应用程序数据缓存中使用

                              SqlCommand cmd = new SqlCommand(sql,conn);                                   

                              SqlCacheDependency scd = new SqlCacheDependency(cmd);

                              Cache.Insert(...,scd,...);

                              注意:

                                   a).     必须设置完全限定名称的数据表。即表名前面需要加所有者,如dbo.test。

                                   b).     必须明确设置所访问数据库列名称,不能使用“*”。

                                   c).     必须保证不是聚合函数。如COUNT、MAX等。

 

               1.3     比较、区别

 

 

SQL SERVER 7.0/2000

SQL SERVER 2005

实现机制

轮询

通知传递服务(Service Broker)

是否需要配置启用

需要

不需要,内置支持

数据更改检测

限于表级更改监测

表级、行级更改监测

                         并且很明显,SQL SERVER 2005的缓存机制更加高效。另外,SqlCacheDependency类还特别结合SQL SERVER 2005 进行了优化:

                              a).     使用SQL SERVER 2005 时,SqlCacheDependency类支持与System.Data.SqlClient.SqlDependency类进行集成。应用程序可创建SqlDependency对象,并通过OnChanged事件处理程序接受通知进行注册。这样,应用程序不仅可以使用Sql server 2005的查询通知机制来监测使用SQL查询结果无效的数据更改,并将缓存对象从缓存中移除,而且还可以轻松获取数据更改通知,以便刷新缓存。(从这里可以看出,当触发onRemoveCallback委托的时候,数据已经从缓存里面删除了,这样一来可以手动在委托里面添加缓存,或者干脆设置成null,让他下次调用的时候再缓存。)

                              b).     不仅向应用程序添加缓存依赖项,还可以与@OutputCache指令一起使用,以生成依赖于SqlServer数据库表的输出缓存的页面或用户控件。对于用户控件,@OutputCache指令不支持使用SQL SERVER 2005 的查询通知(即onRemoveCallback委托)。

 

 

     二、System.Web.Caching.Cache  Insert和Add区别

          2.1     Add方法

                    object Add(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback);

          2.2     Insert方法

                    void Insert(string key, object value);

                    void Insert(string key, object value, CacheDependency dependencies);

                    void Insert(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration);

                    void Insert(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemUpdateCallback onUpdateCallback);

                    void Insert(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback);

          2.3     比较、区别

               a).     Insert方法支持5种重载,使用灵活,而Add方法必须提供7个参数;

               b).     Add方法可以返回缓存项的数据对象,Insert 返回Void;

               c).     添加重复缓存情况下,Insert会替换该项,而Add方法会报错。

 

     三、     CacheDependency、AggregateCacheDependency、SqlCacheDependency

          3.1     CacheDependency是AggregateCacheDependency和SqlCacheDependency的父类。主要用于在应用程序数据缓存对象与文件、缓存键、文件或缓存键的数组或另外一个CacheDependency对象之间建立依赖关系。CacheDependency监视依赖关系比便在任何对象更改时自动移除缓存对象。CacheDependency可以监测一组(到文件或目录的)文件路径的更改情况。

          3.2     AggregateCacheDependency主要用于实现聚合缓存依赖。如一笔数据同时对两个表进行缓存依赖,一旦其中任何一个表数据更改缓存将失效。

          3.3     SqlCacheDependency将应用程序数据缓存对象、页面输出缓存、数据源控件等与指定SQL Server数据库表或Sql Server 2005 查询结果之间建立缓存依赖关系,在表发生更改(Sql Server 2005 行级别更改)时,自动从缓存中删除和重新添加与该表关联的缓存对象。一般而言:

                    SqlCacheDependency (SqlCommand)      用于SQL SERVER 2005
                         SqlCacheDependency (数据库名, 表名)      用于SQL SERVER 7.0/2000 

结束

错误:无法启用数据库中的 Service Broker

解决方案:

   Service Broker 标识符在同一网络上的所有实例中应是唯一的。否则,消息可能被误传。
   那么怎么能让数据库也能使用Service Broker呢?

ALTER DATABASE TpriUserManage SET NEW_BROKER
ALTER DATABASE TpriUserManage SET ENABLE_BROKER

posted on 2009-03-09 17:09  Robin99  阅读(1018)  评论(0编辑  收藏  举报