SqlCacheDependency特性

SqlCacheDependency特性实际上是通过System.Web.Caching.SqlCacheDependency类来体现的。通过该类,可以在所有支持的SQL Server版本(7.0,2000,2005)上监视特定的SQL Server数据库表,并创建依赖于该表以及表中数据行的缓存项。当数据表或表中特定行的数据发生更改时,具有依赖项的数据项就会失效,并自动从Cache中删除该项,从而保证了缓存中不再保留过期的数据。
由于版本的原因,SQL Server 2005完全支持SqlCacheDependency特性,但对于SQL Server 7.0和SQL Server 2000而言,就没有如此幸运了。毕竟这些产品出现在.Net Framework 2.0之前,因此它并没有实现自动监视数据表数据变化,通知ASP.NET的功能。解决的办法就是利用轮询机制,通过ASP.NET进程内的一个线程以指定的时间间隔轮询SQL Server数据库,以跟踪数据的变化情况。

要使得7.0或者2000版本的SQL Server支持SqlCacheDependency特性,需要对数据库服务器执行相关的配置步骤。有两种方法配置SQL Server:使用aspnet_regsql命令行工具,或者使用SqlCacheDependencyAdmin类。

1、利用aspnet_regsql工具

aspnet_regsql工具位于Windows\Microsoft.NET\Framework\[版本]文件夹中。如果直接双击该工具的执行文件,会弹出一个向导对话框,提示我们完成相应的操作:

4-1.gif
图1 aspnet_regsql工具

如图1所示中的提示信息,说明该向导主要用于配置SQL Server数据库,如membership,profiles等信息,如果要配置SqlCacheDependency,则需要以命令行的方式执行。例如,数据库名为Pubs,则命令为:
aspnet_regsql -S localhost -E -d Pubs -ed

以下是该工具的命令参数说明:
-? 显示该工具的帮助功能;
-S 后接的参数为数据库服务器的名称或者IP地址;
-U 后接的参数为数据库的登陆用户名;
-P 后接的参数为数据库的登陆密码;
-E 当使用windows集成验证时,使用该功能;
-d 后接参数为对哪一个数据库采用SqlCacheDependency功能;
-t 后接参数为对哪一个表采用SqlCacheDependency功能;
-ed 允许对数据库使用SqlCacheDependency功能;
-dd 禁止对数据库采用SqlCacheDependency功能;
-et 允许对数据表采用SqlCacheDependency功能;
-dt 禁止对数据表采用SqlCacheDependency功能;
-lt 列出当前数据库中有哪些表已经采用sqlcachedependency功能。

以上面的命令为例,说明将对名为Pubs 的数据库采用SqlCacheDependency功能,且SQL Server采用了windows集成验证方式。我们还可以对相关的数据表执行aspnet_regsql命令,如:
aspnet_regsql -S localhost -E -d Pubs -t table1 -et
aspnet_regsql -S localhost -E -d Pubs -t table2 -et
aspnet_regsql -S localhost -E -d Pubs -t table3 -et

当执行上述的四条命令后,aspnet_regsql工具会在Pubs 数据库中建立一个名为AspNet_SqlCacheTablesForChangeNotification的新数据库表。该数据表包含三个字段。字段tableName记录要追踪的数据表的名称,例如在Pubs 中,要记录的数据表就包括table1、table2和table3。notificationCreated字段记录开始追踪的时间。changeId作为一个类型为int的字段,用于记录数据表数据发生变化的次数。如图2所示:

4-2.gif
图2 AspNet_SqlCacheTablesForChangeNotification数据表

除此之外,执行该命令还会为Pubs数据库添加一组存储过程,为ASP.NET提供查询追踪的数据表的情况,同时还将为使用了SqlCacheDependency的表添加触发器,分别对应Insert、Update、Delete等与数据更改相关的操作。例如Product数据表的触发器:
CREATE TRIGGER dbo.[table1_AspNet_SqlCacheNotification_Trigger] ON [table1]
FOR INSERT, UPDATE, DELETE AS BEGIN
SET NOCOUNT ON
EXEC dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure N'table1'
END

其中,AspNet_SqlCacheUpdateChangeIdStoredProcedure即是工具添加的一组存储过程中的一个。当对table1数据表执行Insert、Update或Delete等操作时,就会激活触发器,然后执行AspNet_SqlCacheUpdateChangeIdStoredProcedure存储过程。其执行的过程就是修改AspNet_SqlCacheTablesForChangeNotification数据表的changeId字段值:
CREATE PROCEDURE dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure
@tableName NVARCHAR(450)
AS
BEGIN
UPDATE dbo.AspNet_SqlCacheTablesForChangeNotification WITH (ROWLOCK) SET changeId = changeId + 1
WHERE tableName = @tableName
END
GO

2 利用SqlCacheDependencyAdmin类

我们也可以利用编程的方式来来管理数据库对SqlCacheDependency特性的使用。该类包含了五个重要的方法:

DisableNotifications 为特定数据库禁用 SqlCacheDependency 对象更改通知
DisableTableForNotifications 为数据库中的特定表禁用 SqlCacheDependency 对象更改通知
EnableNotifications 为特定数据库启用 SqlCacheDependency 对象更改通知
EnableTableForNotifications 为数据库中的特定表启用 SqlCacheDependency 对象更改通知
GetTablesEnabledForNotifications 返回启用了 SqlCacheDependency 对象更改通知的所有表的列表

表1 SqlCacheDependencyAdmin类的主要方法

假设我们定义了如下的数据库连接字符串:
const string connectionStr = "Server=localhost;Database=Pubs";

那么为数据库Pubs启用SqlCacheDependency对象更改通知的实现为:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SqlCacheDependencyAdmin.EnableNotifications(connectionStr);
}
}

为数据表table1启用SqlCacheDependency对象更改通知的实现则为:
SqlCacheDependencyAdmin.EnableTableForNotifications(connectionStr, "table1");

如果要调用表1中所示的相关方法,需要注意的是访问SQL Server数据库的帐户必须具有创建表和存储过程的权限。如果要调用EnableTableForNotifications方法,还需要具有在该表上创建SQL Server触发器的权限。

虽然说编程方式赋予了程序员更大的灵活性,但aspnet_regsql工具却提供了更简单的方法实现对SqlCacheDependency的配置与管理。PetShop 4.0采用的正是aspnet_regsql工具的办法,它编写了一个文件名为InstallDatabases.cmd的批处理文件,其中包含了对aspnet_regsql工具的执行,并通过安装程序去调用该文件,实现对SQL Server的配置。

使用SqlCacheDependency方法

private static void InsertConfigToCache(string sysCode)
{
SysConfig sc = SystemConfigRules.GetBySysCode(sysCode);
if(sc!=null)
{
int cacheDuration = int.Parse(ConfigurationManager.AppSettings["CacheDuration"]);
// Create a AggregateCacheDependency object from the factory
AggregateCacheDependency cd = GetDependency();
// Store the output in the data cache, and Add the necessary AggregateCacheDependency object
HttpRuntime.Cache.Add(sysCode, sc.SysValue, cd, DateTime.Now.AddHours(cacheDuration), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
}
}

public static AggregateCacheDependency GetDependency() {
AggregateCacheDependency dependency = new AggregateCacheDependency();
try {
dependency.Add(new SqlCacheDependency(ConfigurationManager.AppSettings["CacheDatabaseName"].ToString(), "table1"));
} catch (Exception ex) {
throw ex;
}
return dependency;
}

table1与表AspNet_SqlCacheTablesForChangeNotification中的值必须相等,区分大小写。
否则会出现如下错误:

没有为 SQL 缓存通知启用数据库“recrweb”中的“SYS_CONFIG”表。
请确保该表存在,并确保用于缓存依赖项的表名称与缓存通知注册中使用的表名称完全相同。
若要为 SQL 缓存通知启用表,请使用 SqlCacheDependencyAdmin.EnableTableForNotifications 方法或命令行工具 aspnet_regsql。
有关如何使用此工具的详细信息,请运行“aspnet_regsql.exe -?”。
若要获取数据库中已启用表的列表,请使用 SqlCacheDependencyManager.GetTablesEnabledForNotifications 方法或命令行工具 aspnet_regsql.exe。"

在web.config里面的system.web节点里面增加下面一段话:

< caching >
< sqlCacheDependency enabled = " true " pollTime = " 10000 " >
< databases >
< add name = " Pubs " connectionStringName = " SQLConnString1 " pollTime = " 10000 " />
</ databases >
</ sqlCacheDependency >
</ caching >

在根节点下增加如下:

<connectionStrings>
<add name="SQLConnString1" connectionString="server=.;database=Pubs;user id=sa;password=sa;min pool size=4;max pool size=4;" providerName="System.Data.SqlClient"/>
</
connectionStrings>

在appSettings节点下增加:

<add key="CacheDuration" value="12"/>
<add key="CacheDatabaseName" value="Pubs"/>

原文地址:https://www.cnblogs.com/ronli/p/1652156.html