學習之路十九:模仿ASP.NET的緩衝依賴自訂緩衝機制細說 ASP.NET Cache 及其進階用法PetShop之ASP.NET緩衝系統緩衝全解析6:資料庫緩衝依賴

來源:互聯網
上載者:User

項目的效能一直處於中下等的水平,也一直在摸索著,自從前幾周最佳化了WCF那一塊之後,速度明顯提高了,可是程式還不是理想中的要求,所以還要繼續努力!

一丶情境

前一段時間發現多個用戶端在第一次串連Server的時候會頻繁擷取同樣的資料,也就說每個用戶端擷取資料都要去資料庫尋找一次,同一時刻多次的去資料庫擷取資料也是一件很費時間的事!

想來想去,決定把那些基本不變的資料緩衝在Server,最後用戶端擷取資料的時候就不需要直接尋找資料庫了!

上網查了一下關於設計緩衝機制的資料,大部分都是ASP.NET Cache的文章!

雖然Winform也可以使用ASP.NET Cache,不過在我逐步研究的時候,發現它並不適合我們的項目,主要有下面幾個原因:

1. 需要把連接字串配置到App.config中,而我們項目中的連接字串是單獨放在一個指定的檔案中的(這是阻礙我使用ASP.NET Cache的最大原因)

2. 有的時候需要使用命令來開始SQL Server緩衝依賴通知(或者通過代碼來開啟),以及設定檔也需要一些修改

推薦文章:① 細說 ASP.NET Cache 及其進階用法

     ② PetShop之ASP.NET緩衝

     ③ 並發環境下的緩衝容器效能最佳化(上):不可變的雜湊表

     ④ 系統緩衝全解析6:資料庫緩衝依賴

二丶學習

雖然不能把它應用到我們項目中,不過我還是繼續研究了一下它,並且在學習中我找到了一些自訂緩衝的靈感!

當資料庫資料發生更新時,ASP.NET Cache為什麼會自動刪除快取資料呢,最重要的有兩點:

1. 當開啟緩衝依賴的時候,會在你需要緩衝的表中添加一個觸發器,然後會有一張表專門記錄緩衝的表(由觸發器添加)最大更新時間

2. 會輪詢資料庫,也就是開啟一個Timer一直去監測資料庫

三丶思考

所以鑒於以上的想法,我決定自訂緩衝,想法有三個方面:

1. 也是開啟一個Timer一直去監測你要緩衝的資料表(每建立一個緩衝依賴就會啟動一個Timer)

2. 定義一個HasChange屬性(學習ASP.NET Cache的),記錄資料庫表資料是否發生改變了

3. 我們資料庫中每一張表都有一個UpDT的欄位,專門記錄最新動向的時間(我可以通過比較前後兩次時間來判斷資料是否發生了變化)

四丶實現

  1. 定義一個緩衝基類(BaseCache),如下:

 1     public class BaseCache 2     { 3         private DateTime? _tableMaxUpdateTime = DateTime.Now; // 第一次記錄表中資料的最大更新時間 4         private string _getMaxUpdateTimeSQL = string.Empty; 5         private Timer _timer = new Timer(3000); // 開啟時鐘一直監測資料庫是否變化 6         private bool _hasChange = false; 7  8         protected BaseCache(string getMaxUpdateTimeSQL) 9         {10             _getMaxUpdateTimeSQL = getMaxUpdateTimeSQL;11             _tableMaxUpdateTime = GetMaxUpdateTimeByTable(getMaxUpdateTimeSQL);  //第一次擷取最新時間12             _timer.Elapsed += _timer_Elapsed;13             _timer.Start();14         }15 16         protected bool HasChange  //資料是否發生變化的標記17         {18             get { return _hasChange; }19             set { _hasChange = value; }20         }21 22         private void _timer_Elapsed(object sender, ElapsedEventArgs e)  //輪詢資料庫23         {24             try25             {26                 DateTime? latestMaxUpdateTime = GetMaxUpdateTimeByTable(_getMaxUpdateTimeSQL); //擷取最新的更新時間27                 if (Convert.ToDateTime(_tableMaxUpdateTime).CompareTo(latestMaxUpdateTime) != 0)  //比較前後兩次的時間是否相同28                 {29                     _tableMaxUpdateTime = latestMaxUpdateTime;30                     HasChange = true;31                 }32             }33             catch (Exception exception)34             {35                 LoggingManager.WriteLog(LogLevel.Exception, exception.Message + Environment.NewLine + exception.StackTrace );36             }37         }38 39         private DateTime? GetMaxUpdateTimeByTable(string getMaxUpdateTimeSQL)40         {41             return new DAL.Cache().GetMaxUpdateTime(getMaxUpdateTimeSQL);42         }43 44         public virtual void LoadCache() { }45     }

   2. 定義具體的緩衝依賴項 ProductClassCacheDependency,繼承BaseCache

 1     public class ProductClassCacheDependency : BaseCache 2     { 3         private static Dictionary<int, ProClassInfo> _productClassCache = new Dictionary<int, ProClassInfo>(150);  //通過定義靜態變數來作為緩衝容器 4         private static object _obj = new object(); 5  6         public ProductClassCacheDependency(string getMaxUpdateTimeSQL) 7             : base(getMaxUpdateTimeSQL) 8         { 9             LoadCache();10         }11 12         public override void LoadCache()13         {14             Dictionary<int, ProClassInfo> productCalssInfo = new ProClass().GetAllProductClassInfos();15             if (productCalssInfo != null)16             {17                 _productClassCache.Clear();18                 _productClassCache = productCalssInfo;19             }20         }21 22         public Dictionary<int, ProClassInfo> ProductClassCache23         {24             get { return UpdateCache(); }25         }26 27         public Dictionary<int, ProClassInfo> UpdateCache()28         {29             if (HasChange) //採用雙判斷和鎖來實現同步機制30             {31                 lock (_obj) 32                 {33                     if (HasChange)34                     {35                         LoadCache();36                         HasChange = false;37                     }38                 }39             }40             return _productClassCache;41         }42     }

   3. 定義緩衝代理CacheProxy,調用緩衝的進入點

 1     public class CacheProxy 2     { 3         private static CacheProxy _cacheProxy = null; 4         private static object _obj = new object(); 6         private static ProductClassCacheDependency _productClassCache = null; 8  9         private CacheProxy() { }10 11         static CacheProxy() { }12 13         public static CacheProxy Cache14         {15             get16             {17                 if (_cacheProxy == null)18                 {19                     lock (_obj)20                     {21                         return _cacheProxy ?? (_cacheProxy = new CacheProxy());22                     }23                 }24                 return _cacheProxy;25             }26         }27 33         public ProductClassCacheDependency ProductClassCache34         {35             get { return _productClassCache ?? (_productClassCache = new ProductClassCacheDependency("SELECT MAX(UpDT) FROM proDTProClass")); }  
42        //這邊可能處理的不好,沒有ASP.NET Cache直接傳一個表名好,需要改進36 } 43 public void LoadAllCache() //程式啟動的時候就載入所有的緩衝44 {46 _productClassCache = ProductClassCache;47 }48 }

   4. 調用方式

1  if(CacheProxy.Cache.ProductClassCache.ProductClassCache.ContainsKey(1) && CacheProxy.Cache.ProductClassCache.ProductClassCache != null)
  {
    CacheProxy.Cache.ProductClassCache.ProductClassCache[1]
  }

 

五丶總結

  經過了兩三周的辛苦努力終於結束了,其實這個過程也痛苦的(主要是不怎麼會設計代碼,想的頭都大了),不過結果還是挺好的!

  如果覺得文章裡哪裡說的不好的,還請指出啊,我知道代碼還需要修改,大牛們可以多提提建議哦,一定會虛心接受的!

 

已同步至:程式猿個人文章目錄索引

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.