需要C#/ SQL数据库监听器帮助

我需要连续监视数据库行以检查更改(更新)。 如果其他来源有一些更改或更新,应该在我的应用程序上触发事件(我正在使用WCF)。 有没有办法连续监听数据库行以进行更改?

我可能有更多的事件来监视同一个表中的不同行。 在表现方面有任何问题。 我正在使用C#Web服务来监视SQL Server后端。

我前段时间有一个非常相似的要求,我使用CLR SP解决了这个问题,将数据推送到消息队列中。

为了简化部署,我创建了一个带有一个名为SendMessage的微小function的CLR SP,它只是将消息推入消息队列,并使用AFTER INSERT触发器(正常触发器,而不是CLR触发器)将其绑定到我的表。

在这种情况下,性能是我的主要关注点,但我对它进行了压力测试,并且它大大超出了我的预期。 与SQL Server Service Broker相比,它是一个非常易于部署的解决方案。 CLR SP中的代码也非常简单。

您可以在各个表上使用AFTER UPDATE触发器将项添加到SQL Server Service Broker队列。 然后将排队的通知发送到您的Web服务。

另一张海报提到了SqlDependency,我也想提到它,但MSDN文档有点奇怪,它提供了一个Windows客户端示例,但也提供了这个建议:

SqlDependency旨在用于ASP.NET或中间层服务,其中存在相对较少数量的服务器,这些服务器具有对数据库的活动依赖性。 它不是设计用于客户端应用程序,其中数百或数千台客户端计算机将为单个数据库服务器设置SqlDependency对象。

参考

“连续”监控可能意味着每隔几小时,几分钟,几秒甚至几毫秒。 此解决方案可能不适用于毫秒更新:但如果您只需要每分钟“监视”一次表,则可以让外部进程检查表以获取更新。 (如果存在DateTime列。)然后,您可以处理已更改或新添加的行并执行所需的任何通知。 所以你不会听取改变,你会检查它们。 以这种方式进行检查的一个好处是,如果在给定的时间段内更新了很多行,那么你就不会冒很大的性能损失,因为你将它们放在一起(而不是响应每个行)并且每个人都有所变化。)

我考虑了CLRfunction的想法或在从表中成功插入/更新/删除数据后调用服务的类型。 在这种情况下,这甚至是好的吗?

可能这不是一个好主意,但我猜它仍然比进入表触发地狱更好。

我假设你的问题是你想在每次数据修改后做一些事情,比方说,重新计算一些价值或其他什么。 让数据库对此负责并不是一个好主意,因为它会对性能产生严重影响。

您提到要检测不同表上的插入,更新和删除。 按照您的方式进行操作,这将要求您为每个表设置三个触发器/ CLR函数,并让它们将事件发布到您的WCF服务(甚至在sql server中可用的.net子集中支持吗?)。 WCF服务根据收到的事件采取适当的操作。

解决问题的更好方法是将检测数据修改的责任从数据库转移到应用程序。 实际上,这可以非常容易和有效地实现。

每个表都有一个主键(int,GU​​ID或其他)和一个timestamp列,指示上次更新条目的时间。 这是一个在乐观并发场景中经常会看到的设置,因此甚至可能不需要更新架构定义。 但是,如果您需要添加此列并且无法使用数据库卸载更新应用程序的时间戳,则只需为每个表写一个更新触发器,在每次更新后更新时间戳。

为了检测修改,您的WCF服务/监视应用程序以给定的时间间隔构建具有主键/时间戳对的本地字典(最好是哈希表)。 使用数据库中的覆盖索引,此操作应该非常快。 下一步是比较词典和voilá,你去。

但是这种方法有一些警告。 其中一个是每个表的记录总和,另一个是更新频率(如果它变得太低而无效),另一个问题是如果你需要访问修改/插入之前的数据。

希望这可以帮助。

为什么不使用SQL Server Notification服务? 我认为这正是你要找的东西。 浏览通知服务的文档,看看是否符合您的要求。

我觉得这里有一些好主意; 从可伸缩性的角度来看,我认为将支票外部化(例如Paul Sasik的答案)可能是迄今为止最好的(对他而言+1)。

如果出于某种原因,您不想将检查外部化,那么另一个选择是使用HttpCache来存储观察者和回调。

简而言之,当您将记录放在要监视的数据库中时,还要将其添加到缓存中(使用.Add方法)并在其上设置SqlCacheDependency,并回调您要调用的任何逻辑。调用依赖项并从缓存中弹出该项。