【狀態保持】Cache 基於SQL 數據庫 的緩存依賴 輪詢機制詳解


 

首先聲明一下如果您還不了解什么是Cache(緩存)請您先搜一下有關信息然后再看這篇文章。

當數據庫中的信息發生變化的時候,應用程序能夠獲取變化的通知是緩存依賴得以實現的基礎。應用程序可以通過兩種途徑獲取數據變化的信息:

  1. 數據庫通知  當數據庫中的信息發生變化的時候,數據庫會主動通知Framework 或者說通知應用程序。
  2. 輪詢(今天的重點) 數據庫不能通知的時候,應用程序可以主動定期訪問數據庫(在配置文件中可以配置間隔多長時間訪問一次),檢查數據是否發生變化。

     第一種 數據庫通知是最理想的方式,但是許多數據庫都不支持這個方法,SQL server 2005 + 的版本支持這個方法,如果數據庫不支持通知機制比如SQL server 2000 數據庫 現在主機比較普遍的數據庫,那么我們就得通過輪詢機制來實現。

     輪詢:  使用輪詢的話也不可能在重新查一次然后再和以前的數據做比較,如果這樣的話如果我一個表里面有1000行數據我要是讀100次的話是不是得比較1000 x 100 次,顯然這種方法是不可行的,那怎么辦捏。大家都學過觸發器吧,今天的輪詢機制就是通過觸發器來實現的。

實現步驟簡單分析:
     首先創建一個用於記錄監控信息的表,表的字段就兩個一個是表名,一個是版本號。然后,對需要監控的變增加一個觸發器,當表的內容發生變化的時候進行觸發。我們可以用insert delete update 觸發器,如果一旦觸發以上動作就在把那個監控表的版本號字段加1。
上面的步驟要我們自己動手實現起來很麻煩,沒關系跟着微軟混是不會吃虧滴,微軟早就為我們提供好了一個工具叫Aspnet_regsql.exe 這個工具位於C:\Windows\Microsoft.NET\Framework\v2.0.50727這個路徑下(也不一定但是一般就是這個路徑)好了有工具了具體怎么用呢?具體幫助請運行Aspnet_regsql /? 查看下面列出本文要用到的參數
  -U 用戶名
  -P 密碼
  -d 數據庫名稱,默認為aspnetdb數據庫
  -ed 為數據庫打開SQL緩存依賴支持
  -dd 關閉數據庫的SQL緩存依賴支持
  -et 指定SQL緩存依賴使用的表,需要使用-t指定表名
  -dt 禁用SQL 緩存依賴使用的表,需要使用-t指定表名
  -t 指定表名
  -lt 列出啟用緩存依賴的表名
啟用數據庫House 緩存依賴支持,並對Home表啟用緩存依賴,如下:

  aspnet_regsql -S . -E -ed -d House -et -t Home

 

運行后數據庫會發生以下變化:
1. 增加了一個名稱為AspNet_SqlCacheTablesForChangeNotification的表
2. Home表中增加了一個觸發器

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER TRIGGER [Home_AspNet_SqlCacheNotification_Trigger] ON [dbo].[Home]
                       FOR INSERT, UPDATE, DELETE AS BEGIN
                       SET NOCOUNT ON
                       EXEC dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure N'Home'
                       END

3. 增加了幾個存儲過程  如下圖

下面咱打開它建的那個表看看是什么東東

是不是和開始咱描述的步驟差不多它這還多了一個有關時間的列

ok 下面咱手動修改一個Home表中的數據看看這個監視表有什么變化

 

怎么樣 changeId 變了吧!應用程序就是定期查詢這個表的變化然后確定是否更新緩存。

數據庫配置完畢,在看看網站怎么配置吧!首先,打開web.config加入如下代碼  在system.web 節點下

<!-- 基於數據庫的緩存依賴 -->
    <caching>
      <sqlCacheDependency enabled="true" pollTime="500">
        <databases>
          <add name="pubs" connectionStringName="pubs" pollTime="500"/>
        </databases>
      </sqlCacheDependency>
    </caching>

其中pollTime 屬性 就是應用程序間隔多長時間主動訪問一次數據庫默認為1分鍾,單位ms 注意最低為500ms  這里是為了演示效果明顯 設到最低
下面是測試代碼

 

protected System.Text.StringBuilder sbHtml = new System.Text.StringBuilder();
    protected void Page_Load(object sender, EventArgs e)
    {
        List<Home> list = Cache["homeList"] as List<Home>;
        if (list == null)
        {
            Response.Write("<h3>從數據庫中獲得的數據</h3>");
            HouseEntities houseEntities = new HouseEntities();
            list = houseEntities.Home.ToList<Home>();
            Cache["homeList"] = list;
            //基於數據庫的緩存依賴
            SqlCacheDependency sqldep = new SqlCacheDependency("pubs", "Home");
            Cache.Insert("homeList",list,sqldep);
        }
        else
        {
            Response.Write("<h3>從緩存中獲得的數據</h3>");
        }
        
        foreach (Home item in list)
        {
            sbHtml.Append("Id:" + item.Id + "Name:" + item.Name + "Address:" + item.Address + "<br/>");
        }


    }

注意:SqlCacheDependency sqldep = new SqlCacheDependency("pubs", "Home");
第一個參數是配置文件中的<add> 節點下的name 屬性的值,第二個參數是表名

運行效果:

1. 第一次訪問

2 . 刷新一次

3. 改一下數據庫中的數據

4. 刷新一次頁面


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM