14

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

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

4

6 回答 6

9

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

另一个发帖人提到了 SqlDependency,我也想提,但 MSDN 文档有点奇怪,因为它提供了一个 windows 客户端示例,但也提供了以下建议:

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

参考

于 2010-01-28T05:46:54.980 回答
5

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

为了简化部署,我创建了一个 CLR SP,它带有一个名为的小函数SendMessage,它只是将消息推送到消息队列中,并使用 AFTER INSERT 触发器(普通触发器,而不是 CLR 触发器)将它绑定到我的表。

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

于 2010-02-27T10:34:43.757 回答
2

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

于 2010-02-21T06:19:01.407 回答
2

我思考了一个 CLR 函数的想法,或者在成功插入/更新/删除表中的数据后调用服务的那种东西。在这种情况下还好吗?

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

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

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

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

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

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

不过,这种方法有一些注意事项。其中一个是每个表的记录总和,另一个是更新频率(如果它变得太低则无效),另一个精确点是您是否需要在修改/插入之前访问数据。

希望这可以帮助。

于 2010-02-23T18:44:59.033 回答
1

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

于 2010-02-24T17:43:55.260 回答
0

我认为这里有一些很棒的想法;从可扩展性的角度来看,我会说外部化检查(例如 Paul Sasik 的答案)可能是迄今为止最好的一个(对他+1)。

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

简而言之,当您将记录放入要查看的数据库中时,您还可以将其添加到缓存中(使用 .Add 方法)并在其上设置 SqlCacheDependency,并在调用依赖项并将项目从缓存中弹出。

于 2010-02-26T13:40:19.407 回答