|
|
|
|
|
SqlDependency是outputcache網(wǎng)頁緩存的一個參數(shù),它的作用是指定緩存失效的數(shù)據(jù)庫依賴項,可以具體到數(shù)據(jù)庫和表。
SqlDependency能解決什么問題?
Asp.Net中的cache可以設(shè)置一個過期時間,但設(shè)置多久合適呢?長了浪費,短了就失去緩存的意義了。使用SqlDependency進行緩存則可以解決這個問題。
SqlDependency是.net2.0封裝的一個類型,要配合sql2005或以上版本才能使用。
另外,SqlDependency類需要數(shù)據(jù)庫的ServiceBroker來支持,當數(shù)據(jù)庫中的數(shù)據(jù)發(fā)生變化時通知應用程序更新緩存,這才是最有效的緩存方式。
SqlDependency配合ServiceBroker實現(xiàn)緩存
步驟一:
sql數(shù)據(jù)庫必須開啟ServiceBroker服務(wù),首先檢測是否已經(jīng)啟用ServiceBroker,檢測方法:
Select DATABASEpRoPERTYEX('數(shù)據(jù)庫名稱','IsBrokerEnabled')
--1表示已經(jīng)啟用0表示沒有啟用
步驟二:
如果ServiceBroker沒有啟用,使用下面語句啟用:
ALTER DATABASE <數(shù)據(jù)庫名稱> SET ENABLE_BROKER;
步驟三:
在實現(xiàn)基于服務(wù)的SQL數(shù)據(jù)緩存依賴過程中,需要顯式調(diào)用SqlDependency.Start來啟動接受依賴項更改通知的偵聽器。
SqlDependency.Start(connectionString);//推薦將這段代碼加到Global.asax的Application_Start方法中
SqlDependency.Stop(connectionString);//用于關(guān)閉,可加在Global.asax的Application_End方法中
步驟四:緩存實現(xiàn)
使用sqldependency實現(xiàn)緩存的代碼:
public class CacheHelper {
static Cache WebCache = HttpContext.Current.Cache;
static string DefaultConn = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
public static DataTable GetSystemParams() {
if (WebCache["SystemParam"] == null) {
string strSQL = "select uSystemParamID,ParamName,ParamValue,Description from dbo.DTS_SystemParam";
SqlDataAdapter da = new SqlDataAdapter(strSQL, DefaultConn);
SqlDependency dep = new SqlDependency(da.SelectCommand);
dep.OnChange += new OnChangeEventHandler(dep_OnChange);
DataTable tbl = new DataTable(); da.Fill(tbl);
WebCache["SystemParam"] = tbl;
return tbl;
}
else {
return (DataTable) WebCache["SystemParam"];
}
}
private static void dep_OnChange(object sender, SqlNotificationEventArgs e) {
WebCache.Remove("SystemParam");
}
}
注意:
使用 SqlDependency 訂閱查詢通知必須向SQL Server Service Broker提供制定規(guī)則的查詢語句,一般來講,必須是簡單的sql查詢語句(不能用*,不能用top,不能用函數(shù),包括聚合函數(shù),不能用子查詢,包括where后的子查詢,不能用外連接,自連接,不能用臨時表,不能用變量,不能用視圖,不能垮庫,表名之前必須加類似dbo數(shù)據(jù)庫所有者這樣的前綴)例如:select * from table1,select column1 from table1,select count(*) from table1 都是錯誤的sql查詢語句,select column1 from dbo.table1 則是正確的語句。
有關(guān)SqlDependency 的用法,還可以參考如下步驟的實現(xiàn)方式:
1. 注冊連接池
命令:aspnet_regsql -S 192.168.30.220\SQL2K -U sa -P sa -ed -d pubs -et -t test專門注冊連接池的工具 在sql數(shù)據(jù)庫的數(shù)據(jù) 庫改變了,才改變緩存。
參數(shù):
_s 制定注冊的服務(wù)器
_u和 _p 說明是sql數(shù)據(jù)庫的授權(quán)模式、_d 指定數(shù)據(jù)庫的名字
_ed 說明緩存生效。
示例:
aspnet_regsql -S 192.168.30.220\SQL2K -U sa -P sa -ed -d pubs -et -t test
進行outputcache配置
<%@ OutputCache SqlDependency="pubs:test" Duration="100" VaryByParam="id"%>
2. 設(shè)置WebConfig
<connectionStrings>
<add name="mySqlServer" connectionString="Server=192.168.30.220\SQL2K;Database=pubs;uid=sa;pwd=sa;"/>
</connectionStrings>
<caching>
<sqlCacheDependency enabled="true">
<databases>
<add
connectionStringName="mySqlServer"
pollTime="500" />
</databases>
</sqlCacheDependency>
</caching>
name:必須是數(shù)據(jù)庫的名字
connectionStringName:連接字符串的名稱
除了可以建立數(shù)據(jù)庫依賴,還可以建立文件依賴或者其他依賴。
SqlCacheDependency的用法
SqlCacheDependency的使用需經(jīng)過幾個具體的設(shè)置步驟:
該實例中,SqlCacheDependency緩存依賴該數(shù)據(jù)表,即如果表中數(shù)據(jù)發(fā)生了變化,緩存應該失效。
1. 修改web.config,啟用SqlCacheDependency。將下列代碼加入web.config的<system.web>節(jié):
<caching>
<sqlCacheDependency enabled="true">
<databases>
<add connectionStringName="regex_libConnectionString" name="IPBlockedDependency"/>
</databases>
</sqlCacheDependency>
</caching>
這里的connectionStringName指定了在<connectionStrings>中添加的某一個連接字符串。name則是為該SqlCacheDependency起的名字,這個名字將在第3步中用到。
2. 執(zhí)行下述命令,為數(shù)據(jù)庫啟用緩存依賴:
C:\Program Files\Microsoft Visual Studio 9.0\VC>aspnet_regsql -C "Data Source=.;Initial Catalog=regex-lib;Integrated Security=True" -ed -et -t "IPBlocked"這里-C后面的字符串是連接字符串(請?zhí)鎿Q成自己所需要的值),-t參數(shù)后面的字符串是數(shù)據(jù)表的名字。命令執(zhí)行后,數(shù)據(jù)庫中會多出一個AspNet_SqlCacheTablesForChangeNotification表。
3. 在代碼中使用緩存,并為其設(shè)置SqlCacheDependency依賴:
private static string[] GetBlockedIPs()
{
// 1嘗試從緩存中讀取
string[] ips = (string[])HttpContext.Current.Cache[BlockedIPCacheKey];
if (ips != null)
return ips;
// 2從數(shù)據(jù)庫中讀取
using (RxDataContext db = new RxDataContext())
{
ips = db.IPBlockeds.Select(ipb => ipb.UserIP).ToArray();
}
// 3放入緩存
SqlCacheDependency depend = new SqlCacheDependency("IPBlockedDependency", "IPBlocked");
HttpContext.Current.Cache.Insert(BlockedIPCacheKey, ips, depend);
return ips;
}
創(chuàng)建SqlCacheDependency時需要指定web.config中定義的SqlCacheDependency名字,并指定數(shù)據(jù)表的名稱。