一个 SqlCacheDependency 怎样知道当表中的数据发生变化时该与哪些监听者进行通信?

7
我进行了一些研究,发现这个系统的大部分管道都可以看到,但是我不确定当表中的数据发生变化时,SQL Server如何知道何时向任何侦听器(应用程序)发送消息。我将从我理解的地方开始解释,直到我迷失为止。
1)必须在数据库上启用Service Broker,并设置一些权限。
2)应该部署数据库模式。
3)使用aspnet_regsql.exe,为需要缓存数据的数据库和表启用SQL缓存依赖项(此步骤创建一个表来跟踪更改并在表上创建触发器以捕获更改并递增该表中的值)。
4)在.NET应用程序中设置SQL缓存依赖项。例如,在Web应用程序中,您需要添加配置值以获取轮询时间、连接字符串等;在global.asax.cs中启动/停止依赖项,然后在添加项目到缓存时添加SQL缓存依赖项。
4a)启动依赖项的部分内容是设置队列、服务和过程,以进行通信和清理。使用Sql查询分析器,您可以看到连接正在建立,并且正在为应用程序在服务上设置通信信道,以接收来自SQL Server的消息。
5)这就是我困惑的地方。此时,我已经在我的应用程序缓存中缓存了一个项目,并引用了基础表上的SQL缓存依赖项,以便我的应用程序在该行发生更改时可以接收到更改。如果我手动更新该行,我可以看到触发器被触发,并且跟踪表中的值递增1。但是,我没有看到任何与应用程序的通信,也没有在SQL查询分析器中看到任何内容,也没有从缓存中删除该项目。我还没有在数据库中的队列中看到任何内容(动态应用程序队列和标准错误/传输队列都没有)。
我的问题是,是什么在监视数据库中的跟踪表,以便可以向关心此数据更改的SQL依赖项发送消息?
非常感谢任何帮助...我一直在搜寻许多在线参考资料,但找不到任何具体的解释。
1个回答

5
在你的数据库中创建了一个新表,用于保存你想要检查更新的表名和变更号。对于每个设置了sqldependency的表,都会设置一个触发器用于增加我刚才描述的新表中的changeid。
你对这个工作原理的心理模型是反过来的。你的应用程序通过检查日志来确定表格是否已更改。
因此,如果changelog表(我称之为这样)正在跟踪数据库中的两个表格(产品,用户),则它将如下所示。
+Table Name + ChangeNumber +
| Product   | 1            |
+-----------+--------------+
| User      | 1            |
+-----------+--------------+

现在,如果您修改这两个表中的任何内容,触发器将增加ChangeNumber,我们现在知道它们已经更改。
显然,这还有更多细节,但这是一般想法。
注意:应该注意,如果一个或多个表更改,您可以使页面无效,因此,如果您的页面为这两个表设置了依赖关系,如果其中一个表更改,它将使缓存页面无效,并重新缓存更新后的版本。

1
好的,我想我明白了。所以当应用程序启动时,在您的示例中,它将检查Product的当前changeId是否为1,User是否为1。那就是基线。然后根据配置文件中设置的轮询时间,它将访问数据库以检查changeId是否已经增加。如果是这样,它将保留新值以供下一次检查,并将缓存项取消。我刚刚意识到的另一个缺陷是,如果我缓存用户并且其中任何一个用户更改,则所有用户都将从缓存中删除。虽然这不是我的计划,但这样设计依赖关系是有道理的。 - longda
1
我认为应用程序不会轮询,如果您请求的页面具有Product作为SQL依赖项之一,则它将首先访问数据库以查看在更改日志表中是否更改了Product。如果没有更改,则发送缓存页面,如果有更改,则使页面失效。我不确定您所说的所有用户都从缓存中删除是什么意思。如果您有一个显示用户列表和一些详细信息的页面,请将sqldependency设置为User,该页面将被缓存,直到User表中的某些内容发生更改。您没有将表缓存在内存中,而是将所有相关数据缓存在某个页面上,以便无需重新查询。 - The Muffin Man
@longda,如果你还有困难或需要更多帮助,请告诉我。 - The Muffin Man
1
感谢@Nick的帮助!我在我的应用程序中(使用MVC3 + MVC-Mini-Profiler + Nhibernate + SysCache2)发现了一个问题。结果,我使用NHibernate来分析数据库连接的一些代码出现了问题,我认为这是由于从应用程序到数据库进行轮询的调用使用了批处理(?). 无论如何,我切换回标准的NHibernate SQL驱动程序,SQL依赖项就开始工作了。在此过程中,一旦我看到一切正常工作,我意识到这不是正确的解决方案,因为表中的一行更改将清除该缓存区域。 - longda
2
因此,SQL 依赖项已被关闭,我将调查分布式、进程外的缓存,如 Memcache 和 App Fabric/Velocity/无论它今天被称为什么。干杯! - longda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接