這兩天 PetShop is Evil?等對PetShop 的討論很多,我在這裡也發一篇湊湊熱鬧。我下面主要是對Asp.net 2.0新增的緩衝管理方面的內容和PetShop 4的緩衝處理的一個認識,大家一起來學習,交流才能進步,歡迎拍磚頭。
Asp.net 2.0新增的緩衝管理
CacheDependency跟蹤緩衝依賴項,緩衝依賴項可以是應用程式的 Cache 中的檔案、目錄或與其他對象的鍵。
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 查詢的項
AggregateCacheDependency 類監視依賴項對象的集合,以便在任何依賴項對象更改時,該快取項目都會自動移除。數組中的對象可以是 CacheDependency 對象、SqlCacheDependency 對象、從 CacheDependency 派生的自訂對象或這些對象的任意組合.
AggregateCacheDependency 類與 CacheDependency 類的不同之處在於前者允許您將不同類型的多個依賴項與單個快取項目關聯。例如,如果您建立一個從 SQL Server 資料庫表和 XML 檔案匯入資料的頁,則可建立一個 SqlCacheDependency 對象來表示資料庫表的依賴項,以及一個 CacheDependency 來表XML 檔案的依賴項。可建立 AggregateCacheDependency 類的一個執行個體,將每個依賴項添加到該類中,而不是為每個依賴項調用 Cache.Insert 方法。然後,可使用單個Insert 調用使該頁依賴於 AggregateCacheDependency 執行個體。
ASP.NET 2.0 允許您使用 SqlCacheDependency 類建立依賴於資料庫中表或行的快取項目。當表中或特定行中發生更改時,帶有依賴項的項便會失效,並會從緩衝中移除。可以在 Microsoft SQL Server 7.0、SQL Server 2000 和 SQL Server 2005 中設定表的依賴項。如果您使用 SQL Server 2005,還可以設定特定記錄的依賴項。
ASP.NET 2.0 SQL 緩衝依賴項提供以下功能:
1. SQL 緩衝依賴項可用於應用程式緩衝和頁輸出緩衝。
2. 可在 SQL Server 7.0 及更高版本中使用 SQL 緩衝依賴項。
3. 可以在網路園(一台伺服器上存在多個處理器)或網路場(多台伺服器運行同一應用程式)中使用 SQL 緩衝依賴項。
4. 與 SQL 緩衝依賴項關聯的資料庫操作比較簡單,因此不會給伺服器帶來很高的處理成本。
ASP.NET 2.0 為 SQL Server 7.0 和 SQL Server 2000 的緩衝依賴項實現了一個輪詢模型。ASP.NET 進程內的一個線程會以指定的時間間隔輪詢 SQL Server 資料庫,以確定資料是否已更改。如果資料已更改,緩衝依賴項便會失效,並從緩衝中移除。可以在 Web.config 檔案中以聲明方式指定應用程式中的輪詢間隔,也可以使用 SqlCacheDependency 類以編程方式指定此間隔。
對於 SQL Server 7.0 和 SQL Server 2000,SQL 緩衝依賴項僅限於表層級的資料更改。可以將 ASP.NET 配置為輪詢資料庫來確定表中的更改,但不能確定特定行中的更改。
啟用 SQL 緩衝
為了在 SQL Server 7.0 和 SQL Server 2000 中使用 SQL 緩衝依賴項,必須先將 SQL Server 配置為支援緩衝依賴項。ASP.NET 提供了一些工具 + 生產力,可用於配置 SQL Server 上的 SQL 緩衝,其中包括一個名為 Aspnet_regsql.exe 的工具和 SqlCacheDependencyAdmin 類.
SQL Server 2005 為緩衝依賴項實現的模型不同於 SQL Server 7.0 和 SQL Server 2000 中的緩衝依賴項模型。在 SQL Server 2005 中,不需要執行任何特殊的配置步驟來啟用 SQL 緩衝依賴項。此外,SQL Server 2005 還實現了一種更改通知模型,可以向訂閱了通知的應用程式伺服器發送通知,而不是依賴早期版本的 SQL Server 中必需的輪詢模型。
SQL Server 2005 緩衝依賴項在接收通知的更改類型方面更具靈活性。SQL Server 2005 監控對特定 SQL 命令的結果集的更改。如果資料庫中發生了將修改該命令的結果集的更改,依賴項便會使緩衝的項失效。此功能使得 SQL Server 2005 可以提供行層級的通知。
MS PetShop4.0對 緩衝的管理
在PetShop 中,需要對資料表實現Cache。這些Cache都存放在.Net為Web系統提供的Cache集合對象 System.Web.Caching.AggregateCacheDependency中,下面代碼中的紅色標明的代碼就是 AggregateCacheDependency緩衝管理的代碼。
/// <summary>
/// This is the base class for SQL2KCacheDependency implementation that encapsulates common
/// algorithm to retrieve database and table names from configuration file and create
/// the necessary AggregateCacheDependency object
/// </summary>
public abstract class TableDependency : PetShop.ICacheDependency.IPetShopCacheDependency {
// This is the separator that's used in web.config
protected char[] configurationSeparator = new char[] { ',' };
protected AggregateCacheDependency dependency = new AggregateCacheDependency();
/// <summary>
/// The constructor retrieves all related configuration and add CacheDependency object accordingly
/// </summary>
/// <param name="configKey">Configuration key for specific derived class implementation</param>
protected TableDependency(string configKey) {
string dbName = ConfigurationManager.AppSettings["CacheDatabaseName"];
string tableConfig = ConfigurationManager.AppSettings[configKey];
string[] tables = tableConfig.Split(configurationSeparator);
foreach (string tableName in tables)
dependency.Add(new SqlCacheDependency(dbName, tableName));
}
public AggregateCacheDependency GetDependency() {
return dependency;
}
}
下面這個圖就是PetShop 4的緩衝管理類圖
它 使用了眾多的設計模式,例如原廠模式,Factory模式等。但是他的設計也是非常的不靈活,比如說增加一個快取項目,也需要去修改許多地方的代碼,例如 DependencyAccess,微軟在企業類庫中有一個核心組件ObjectBuilder,半年前沒有深入學習,就發了一個這樣的文章MS 的IOC容器(ObjectBuilder)? 。下面的例子中我使用ObjectBuilder進行改造,也就是IoC方式進行改造,最近大家對IOC的典型(Castle)的研究也非常多。
具體的代碼我就不講了.代碼非常的簡單,有兩個基本的單元測試,可以自己下載了研究一下,有什麼問題這裡一起交流。我下面將設定檔和PetShop4的設定檔作個比較。
PetShop4的設定檔
<appSettings>
<!-- Enable data caching -->
<add key="EnableCaching" value="true"/>
<!-- Cache duration (in hours-whole number only) -->
<add key="CategoryCacheDuration" value="12"/>
<add key="ProductCacheDuration" value="12"/>
<add key="ItemCacheDuration" value="12"/>
<!-- Cache dependency options. Possible values: PetShop.TableCacheDependency for SQL Server and keep empty for ORACLE -->
<add key="CacheDependencyAssembly" value="PetShop.TableCacheDependency"/>
<!-- CacheDatabaseName should match the name under caching section, when using TableCacheDependency -->
<add key="CacheDatabaseName" value="MSPetShop4"/>
<!-- *TableDependency lists table dependency for each instance separated by comma -->
<add key="CategoryTableDependency" value="Category"/>
<add key="ProductTableDependency" value="Product,Category"/>
<add key="ItemTableDependency" value="Product,Category,Item"/>
</appSettings>
改造後的設定檔
<configSections>
<section name="AspCacheConfiguration" type="AspCacheDependency.Configuration.AspCacheDependencySettings, AspCacheDependency" />
</configSections>
<AspCacheConfiguration >
<aspCacheProviders>
<add name="Product" type="AspCacheDependency.AspSqlCacheDependency, AspCacheDependency" database="MSPetShop4" table="Product,Category"/>
<add name="Category" type="AspCacheDependency.AspSqlCacheDependency, AspCacheDependency" database="MSPetShop4" table="Category"/>
</aspCacheProviders>
</AspCacheConfiguration>
改造後的緩衝使用就非常的簡單了,而且可以應用於任何的項目,而不會合特定的項目相關。具體例子例如下面單元測試代碼:
[TestMethod]
public void GetAspSqlCacheDependencyCategory()
{
AspSqlCacheDependency sqlCachelDep = AspCacheDependencyFactory.CreateDependency("Category");
Assert.AreEqual(sqlCachelDep.Table, "Category");
AggregateCacheDependency dependency = sqlCachelDep.GetDependency();
Assert.IsNotNull(dependency);
}
代碼下載:AsplCacheDependency.rar