阿宽

Nothing is more powerful than habit!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

SqlCacheDependency使用查询(命令)通知使缓存无效

Posted on 2011-02-26 16:22  宽田  阅读(1514)  评论(0编辑  收藏  举报

系列目录:

SqlDependency缓存用法

Asp.net使用SqlDependency

SqlCacheDependency使用命令通知使缓存无效

CacheDependency用法

AggregateCacheDependency 用法

SqlCacheDependency使用轮流检测技术(轮询)使缓存无效

-------------------------------------------------------------------------------------------

 

 

   数据库缓存依赖(SqlCacheDependency)主要解决的是当数据库的内容发生改变时,如何及时通知缓存,并更新缓存中的数据的问题。

   SqlCacheDependency类在所有受支持的 SQL Server 版本 (7.0, 2000, 2005) 上监视特定的 SQL Server 数据库表,以便在该表发生更改时,自动从 Cache 中删除与该表关联的项。 数据库表发生更改时,将自动删除缓存项,并向 Cache 中添加新版本的项。在使用 SQL Server 2005 数据库时,SqlCacheDependency 类还支持与 System.Data.SqlClient.SqlDependency 类进行集成。使用 SQL Server 2005 的查询通知机制来检测使 SQL 查询结果无效的数据更改。与 SQL 查询关联的任何缓存项都将从 System.Web.Caching.Cache 中移除。在使用 SQL Server 2005 时,可以使用 SqlCacheDependency 类向应用程序的 Cache 添加依赖于 SQL Server 数据库表或 SQL 查询的项。

使用方法:

  1、启用CLR
  在一个消息到达服务队列时,一个包含.Net代码的存储过程sp_DispatcherProc将使用一个队列来派发消息。因此必须启用Sql Server中的CLR功能。启用方法如下:

Use Master
Exec sp_configure 'clr enabled',1
Reconfigure

 

  2、启用 Service Broker。可以通过下边语句查看是否启用。
select DatabasePropertyex('Northwind','IsBrokerEnabled')
--返回1表示true,返加0表示false

 

    启动Service Broker语句如下:

use master
Alter Database Northwind set enable_broker

 

  3、给您的数据库访问帐号授予权限(我用的sa账户,没有操作此步)

GRANT SUBSCRIBE QUERY NOTIFICATIONS TO User

  注意:这一步非常重要, 如果没有权限, 数据库改变的通知将无法接收, cache永远都不会被刷新,我开始是用的sa帐号,死活都不刷新,花了我两天时间调试这个问题, 还是无法给sa授此权限(ms禁止), 所以,换个数据库访问帐号即可.

 

  4.添加数据库连接字符串

  <connectionStrings>
    
<add name="NHibernateSampleDb" providerName="System.Data.SqlClient" 
         connectionString
="Data Source=.; Initial Catalog=NHibernateSample; Persist Security Info=True;User ID=sa;Password=123"/>
  
</connectionStrings>

 

  5.启动SqlDependency监听 

using System.Data.SqlClient;
using System.Web.Caching;

namespace SqlDependencyInAspNet
{
    
public class Global : System.Web.HttpApplication
    {

        
protected void Application_Start(object sender, EventArgs e)
        {
            
// 在应用程序启动时运行的代码
            SqlDependency.Start(System.Configuration.ConfigurationManager.ConnectionStrings["NHibernateSampleDb"].ToString());
        }

        
protected void Application_End(object sender, EventArgs e)
        {
            SqlDependency.Stop(System.Configuration.ConfigurationManager.ConnectionStrings[
"NHibernateSampleDb"].ToString());
        }
    }
}

 

  6.主程序

  在SqlCacheDepencyPage.aspx页面上放一个Gridview用于显示数据。

using System.Data;
using System.Configuration;
using System.Data.SqlClient;
using System.Web.Caching;


namespace SqlDependencyInAspNet
{
    
public partial class SqlCacheDepencyPage : System.Web.UI.Page
    {

        
string connectionString = ConfigurationManager.ConnectionStrings["NHibernateSampleDb"].ToString();
        
protected void Page_Load(object sender, EventArgs e)
        {            
            
if (!IsPostBack)
            {
                GetCacheDependencyData();
            }
        }

        
/// <summary>
        
/// 得到资料
        
/// </summary>
        private void GetCacheDependencyData()
        {
            
if (Cache["TableDate"]!=null)
            {
                System.Diagnostics.Debug.WriteLine(
"调用一次");
            }
            
else
            {
                
using (SqlConnection cn = new SqlConnection(connectionString))
                {
                    
using (SqlCommand cmd = cn.CreateCommand())
                    {
                        cn.Open();
                        cmd.CommandText 
= "select [CustomerId],[Firstname],[Lastname],[Version] from [dbo].[Customer]";
                        SqlCacheDependency dep 
= new SqlCacheDependency(cmd);
                        
//当有DML操作时,onChange事件会接收来自Sql Server通过sq_DispatcherProc存储过程发送给应用程序的消息。                    
                        DataTable dt = new DataTable();
                        
using (SqlDataAdapter adapter = new SqlDataAdapter()) //查询数据
                        {
                            adapter.SelectCommand 
= cmd;
                            adapter.Fill(dt);
                        }
                        
Cache.Insert("TableDate", dt, dep);
                    }
                }
            }

            gvData.DataSource 
= (DataTable)Cache["TableDate"];
            gvData.DataBind();
        }

    }
}

  注意上边代码中红色加粗部分。

 

  7、测试

   运行程序。现在修改数据表中内容。刷新页面,你会发现cache为空,当你不修改任何内容时,cache会存在。