DMSFrame 之SqlCacheDependency(二)

kingkoo發表於2015-06-08

上篇文章介紹的是通知模式的快取機制,這裡介紹的是資料庫輪循模式處理,這種模式對SQL2005以下的支援還是比較好的

引擎原始碼如下:

/// <summary>
    /// 輪循模式
    /// 資料庫快取通知模式
    /// 1.SELECT  DATABASEPROPERTYEX('DATABASENAME','IsBrokerEnabled') 1 表示啟用,0表示未啟用
    /// 2.啟用IsBrokerEnabled
    /// ALTER DATABASE [DATABASENAME] SET NEW_BROKER WITH ROLLBACK IMMEDIATE;
    /// ALTER DATABASE [DATABASENAME] SET ENABLE_BROKER;/ALTER DATABASE [DATABASENAME] SET DISABLE_BROKER;
    /// 3.web.config 新增配置資訊
    /// connectionStrings
    /// 4.設定aspnet_regsql.exe的資訊,aspnet_regsql –S 伺服器名 –U 登陸名 ID –P 密碼 –d 資料庫名  –ed
    /// </summary>
    [Obsolete("適用於資料庫2005以下,2005以上請使用DMSLinqSqlWebCacheNotifyProvider")]
    public class DMSLinqSqlWebCacheProvider : IDMSLinqCacheProvider
    {

        System.Web.Caching.Cache webCache = System.Web.HttpRuntime.Cache;
        private static object syncObj = new object();
        public DMSLinqSqlWebCacheProvider()
        {
            lock (syncObj)
            {
                System.Web.HttpContext context = System.Web.HttpContext.Current;
                if (context != null)
                    webCache = context.Cache;
                else
                    webCache = System.Web.HttpRuntime.Cache;
            }
        }

        public string GetDependencyKey(System.Data.IDbCommand command, string[] tableNames)
        {
            string dependencyKey = command.CommandText;
            foreach (System.Data.IDbDataParameter item in command.Parameters)
            {
                dependencyKey += string.Format("-{0}-{1}", item.ParameterName, item.Value);
            }
#if DEBUG
            System.Diagnostics.Debug.WriteLine(string.Format("{0},use dependency key successfully", dependencyKey));
#endif
            return dependencyKey;
        }

        public object GetCache(string dependencyKey)
        {
            object resultValue = webCache[dependencyKey];
#if DEBUG
            System.Diagnostics.Debug.WriteLine(string.Format("this cache is empty?:{0}", resultValue == null ? "true" : "false"));
#endif
            return resultValue;
        }
        public System.Web.Caching.CacheDependency GetCacheDependency(string connectionString, System.Data.IDbCommand command, string[] tableNames, ref string dependencyKey)
        {
            CacheDependency dependency = null;
            try
            {
                SqlCacheDependencyAdmin.EnableNotifications(connectionString);
                if (!SqlCacheDependencyAdmin.GetTablesEnabledForNotifications(connectionString).Contains(tableNames[0]))
                {
                    SqlCacheDependencyAdmin.EnableTableForNotifications(connectionString, tableNames[0]);
                }
                if (tableNames.Length == 1)
                {
                    dependency = new SqlCacheDependency("DefaultValue", tableNames[0]);
                }
                else
                {
                    AggregateCacheDependency dependency0 = new AggregateCacheDependency();
                    foreach (var item in tableNames)
                    {
                        dependency0.Add(new SqlCacheDependency("DefaultValue", item));
                    }
                    dependency = dependency0;
                }

            }
            catch (Exception ex)
            {
                DMSFrame.Loggers.LoggerManager.Logger.Log(ex, ReflectionUtils.GetMethodBaseInfo(System.Reflection.MethodBase.GetCurrentMethod()), DMSFrame.Loggers.ErrorLevel.Fatal);
            }
#if DEBUG
            System.Diagnostics.Debug.WriteLine(string.Format("Get the sqlcachedependency successfully.{0}", dependency == null ? "false" : "true"));
#endif
            return dependency;
        }
        public void SetCache(System.Web.Caching.CacheDependency dependency, string dependencyKey, object Value)
        {
            if (dependency != null)
            {
#if DEBUG
                System.Diagnostics.Debug.WriteLine(string.Format("Add cache is successfully,{0}", dependencyKey));
#endif
                webCache.Insert(dependencyKey, Value, dependency);
            }
        }
    }
View Code

同樣的,程式碼也要配置一下.

<configSections>
    <section name="DMSLinqCacheProvider" type="DMSFrame.Cache.DMSLinqCacheProvider,DMSFrame"/>
  </configSections>
  <DMSLinqCacheProvider>
    <add key="provider" providerName="MsSql" value="DMSFrame.Cache.DMSLinqSqlWebCacheProvider,DMSFrame"/>
  </DMSLinqCacheProvider>

注意,此處理配置的資料庫連線name必須是 DefaultValue,至於為什麼是這個,可以看下引擎原始碼..呵呵,這裡就不解釋了.....

<connectionStrings>
    <add  name="DefaultValue" providerName="System.Data.SqlClient" connectionString="Integrated Security=False;server=127.0.0.1;database=DATABASE;User ID=sa;Password=sa;Connect Timeout=30;"/>
  </connectionStrings>

 增加支援 sqlCacheDependency 的配置,輪循時間為1000毫秒

 <system.web>    
    <caching>
      <sqlCacheDependency enabled="true" pollTime="1000">
        <databases>
          <add name="DefaultValue" connectionStringName="DefaultValue" pollTime="500" />
        </databases>
      </sqlCacheDependency>
    </caching>
  </system.web>

注: databases也可以重寫輪循時間的哦...呼呼,不要以為這樣就可以了哦..

還要再檢查我們資料庫是否支援這個模式的方式呢.這種模式查詢SQL會自動在表 AspNet_SqlCacheTablesForChangeNotification 新增一行資料..每更新,刪除,插入一次都會增加(更新)一資料的.

怎麼開啟AspNet_SqlCacheTablesForChangeNotification 這個..具體可以參考 

1.為 SQL Server 啟用快取通知
aspnet_regsql.exe -S <Server> -U <Username> -P <Password> -ed -d Northwind -et -t Employees
為 Northwind 資料庫中的 Employees 表啟用快取通知
aspnet_regsqlcache –S 伺服器名稱 –U 登陸ID –P 密碼 –d 資料庫名稱 –t 要追蹤的資料表的名稱 –et

 

注:這種模式比較耗資料庫效能哦!!!!強烈建議用通知模式吧,具體參考文章:

DMSFrame 之SqlCacheDependency(一)

 

相關文章