我经常以以下形式运行查询:
select * from SomeTable where id=12345
我可能一页又一页地运行相同的查询,因为用户需要该行的值。通常我会获取一次并缓存它,但用户可以随时更改该行,并且其他用户也会同时在 SomeTable 中进行更改,因此我无法缓存整个表。我还有一个问题,我们有一个网络服务器集群,所以当缓存失效时我无法在网络服务器上进行内部跟踪。
有什么方法可以检测到该行发生了更改吗? SqlDependecyCache 类可以帮助将单个行发送到多个 Web 服务器吗?是否有某种触发器或其他范例可以通知我的 Web 应用程序?
我想要两全其美 - 网络服务器上的实时缓存更新,但我不想运行任何查询来查看该行是否已更改,因为我可以轻松地再次获取该行。
最佳答案
您需要的是启用 SqlCacheDependency,如 @RenusRusanu 提到的。
我有几个工作示例on my Github site ,随意浏览 the code under my LearningProjects (第三方编辑)
您需要先配置数据库才能使用SqlCacheDependency:
为了使用 SQL 依赖项,我们基本上需要在数据库中配置两件事:
创建由表和存储过程组成的数据库基础设施,为了配置它,我们使用
aspnet_regsql.exe
如下:/* For SQL Server authentication... */ aspnet_regsql.exe -S server -U user -P password -d database -ed /* For Windows Authentication... */ aspnet_regsql.exe -S server -E -d database -ed
创建轮询信息,其中包括指定要监视的表以及该表的触发器以填充所需的基础架构表
/* For SQL Server authentication... */ aspnet_regsql.exe -S server -U user -P password -d database -t tableName -et /* For Windows Authentication... */ aspnet_regsql.exe -S server -E -d database -t tableName -et
代码配置
var s = new SqlCacheDependency("AdventureWorks", "Product");
HttpContext.Current.Cache.Insert(
"products",
h,
s,
Cache.NoAbsoluteExpiration,
Cache.NoSlidingExpiration);
AdventureWorks
name是web.config文件中配置的sql依赖的名称
<caching>
<sqlCacheDependency enabled="true" pollTime="30000" >
<databases>
<add
name="AdventureWorks"
connectionStringName="AdventureWorksPolling" />
</databases>
</sqlCacheDependency>
</caching>
pollTime
可以在 <add ...
中配置元素并将覆盖全局 polltime
或者,您可以依赖 SqlDataSource 控件
为了在使用此控件时启用缓存,您需要设置 DataSourceMode
属性至DataSet
。在这种情况下,您不需要按照之前的说明配置数据库
I just uploaded this example (full working example)
ASPX
<asp:SqlDataSource runat="server" ID="sds"
ConnectionString="<%$ConnectionStrings:pubsConnectionString %>"
CacheDuration="30"
EnableCaching="true"
SelectCommand="select * from jobs"
DataSourceMode="DataSet"
OnSelecting="sds_Selecting">
</asp:SqlDataSource>
<div>
<asp:Literal runat="server" ID="msg" Mode="Encode"></asp:Literal>
</div>
<asp:GridView runat="server" DataSourceID="sds"></asp:GridView>
编辑 1
为了在使用 SqlCacheDependency 时有选择地触发触发器,您需要更新手动生成的触发器。
当您使用 aspnet_regsql -t -et...
配置表时命令,将触发器添加到指定的表中。该触发器负责填充 AspNet_SqlCacheTablesForChangeNotification
SqlCacheDependency 对象使用表来从数据库轮询数据。
触发器看起来像:
ALTER TRIGGER [dbo].[jobs_AspNet_SqlCacheNotification_Trigger] ON [dbo].[jobs]
FOR INSERT, UPDATE, DELETE AS BEGIN
SET NOCOUNT ON
EXEC dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure N'jobs'
END
您可以更新触发器以仅调用 dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedureN'jobs'
当您感兴趣的行更新时的存储过程
我不是 SQL 专家,但我认为找到一种干净的方法来检测已更改的行很容易,例如,谷歌搜索我刚刚找到了这个链接
Most efficient method to detect column change in MS SQL Server
关于asp.net - 在 asp.net 中缓存 sql server 数据,直到行被修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12423970/