Cache应用(sql依赖缓存)

一、引言

  ASP.NET 2.0新增加了不少新的功能和控件。其中,在数据的缓存功能上有了很大的改变。众所周知,数据的缓存功能是十分重要的,我们可以把一些在相对一段时间内不发生改变的数据放在缓存中,这样,就不必要每次去读取数据库,当下次再需要这些数据时,可以直接从缓存中取得,大大增强了效率。
  在asp.net 早期版本(1.1) 中,已经比较好地实现了数据的缓存功能,但有一个小问题,那就是如果数据库中的数据发生了变化,缓存不能在指定的时间内更新,而必须等到缓存失效。比如,在网页中,如果你对商品的一些详细信息,如商品所在的门类使用了页面缓存,那么假如在后台修改了这些信息,用户不会马上看到这些信息,而要延迟一些时间(譬如,页面的缓存到期了)才看到。在某些应用场合,如果你要做到对于数据库的任何更新,都能马上可以在缓存的变化生效的话,在asp.net 1.1中则是比较难实现的,而在asp.net 2.0中,则可以很方便地实现该功能。

二、编码前的准备工作

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

       1、检测是否已经启用Service Broker

       执行Select databasepropertyex('db Name', 'IsBrokerEnabled')   结果:'1' : broker is enabled,'0' :broker is not enabled

       2、启用Service Broker(让相应的数据库启用监听服务,以便支持SqlDependency特性。如果步骤1中的sql语句结果是1,可以跳过步骤2)

        ALTER DATABASE databasename SET ENABLE_BROKER

        注意:有时该sql语句执行的时间会很长,那么请把数据库连接断开(或干脆把Microsoft SQL Server Management关闭重新打开)重新启动连接,执行该            语句只需数秒钟。

        原因可能是:该命令可能需要产生排他锁,然而,当数据库处于连接状态时就不能产生排他锁,所以就一直等待最后挂起。

三、编写代码

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

在Global.asax文件中

     

  void Application_Start(object sender, EventArgs e) 
    {
        //在应用程序启动时运行的代码
        string connStr = BalloonShopConfiguration.DbConnectionString;
        System.Data.SqlClient.SqlDependency.Start(connStr);
    }
    
    void Application_End(object sender, EventArgs e) 
    {
        //在应用程序关闭时运行的代码
        string connStr = BalloonShopConfiguration.DbConnectionString;
        System.Data.SqlClient.SqlDependency.Stop(connStr);
    }

   (2)应用程序数据缓存中编写如下代码:
   
public class CatalogAccessUseSqlCache
    {
        public static DataTable GetDepartments()
        {
            string connStr = BalloonShopConfiguration.DbConnectionString;
            SqlConnection conn=null;
            try
            {
                conn = new SqlConnection(connStr);
                SqlCommand comm = new SqlCommand();
                comm.Connection = conn;
                SqlCacheDependency dep = new SqlCacheDependency(comm);
                comm.CommandType = CommandType.Text;
                comm.CommandText = "SELECT DepartmentID,Name,Description FROM dbo.Department";
                SqlDataAdapter adapter = new SqlDataAdapter(comm);
                conn.Open();
                DataTable dt=new DataTable();
                adapter.Fill(dt);
                System.Web.HttpContext.Current.Cache.Add("GetDepartments", dt, dep,
                    Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
                return dt;
            }
            catch(Exception ex)
            {
                Utilities.LogError(ex);
                throw ex;
            }
            finally
            {
                conn.Close();
            }
        }
    }
private void BindGrid()
   {
       if (HttpContext.Current.Cache["GetDepartments"] == null)
       {
           //Get a DataTable object containing the catalog departments
           //grid.DataSource = CatalogAccess.GetDepartments();
           list.DataSource = CatalogAccessUseSqlCache.GetDepartments();
       }
       else
       {
           list.DataSource = (System.Data.DataTable)HttpContext.Current.Cache["GetDepartments"];
       }
       //Bind the data bound controls to the data source
       list.DataBind();
   }
     (3)与 sqlCommand 参数关联的 SQL 语句必须包括以下内容
     a、必须设置完全限定名称的数据表。即表名前面需要加所有者,如dbo.Department
       b、必须明确设置所访问数据库列名称,不能使用通配符(“*”)。
     例如,不能使用 "select * from Department",而必须使用 "DepartmentID,Name,Description FROM dbo.Department"
     c、必须保证不是聚合函数。如COUNT、MAX等
        经过如上的几个步骤,就基本上完成了sql依赖缓存的代码编写。
 
四、相关知识点的介绍(老生常谈的内容,不过很容易忘记)
      (1)SqlCacheDependency的初始化
      构造函数:public SqlCacheDependency (SqlCommand sqlCmd)。
      (2)System.Web.Caching.Cache Insert和Add区别
     有关Add与Insert方法的详细信息见MSDN:
http://msdn.microsoft.com/zh-cn/library/system.web.caching.cache.add(v=VS.80).aspx
http://msdn.microsoft.com/zh-cn/library/system.web.caching.cache.insert(v=VS.80).aspx
2者的一些区别如下:
a、Insert方法支持5种重载,使用灵活,而Add方法必须提供7个参数;
b、Add方法可以返回缓存项的数据对象,Insert 返回Void;
c、添加重复缓存情况下,Insert会替换该项,而Add方法会报错。
五、小结
    本篇讲解了一些关于Asp.Net数据缓存的一些基本知识,更多的知识点与注意点还需实际使用时注意.
原文地址:https://www.cnblogs.com/smallstone/p/1770044.html