【问题标题】:C#/SQL Database listenerC#/SQL 数据库监听器
【发布时间】:2010-01-28 05:35:20
【问题描述】:

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

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

【问题讨论】:

    标签: c# sql wcf transactions erp


    【解决方案1】:

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

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

    SqlDependency 被设计为使用 在 ASP.NET 或中间层服务中 相对较小的地方 具有依赖关系的服务器数量 主动针对数据库。它是 不是为在客户端使用而设计的 应用程序,其中数百或 成千上万的客户端计算机将 设置 SqlDependency 对象 单个数据库服务器。

    Ref.

    【讨论】:

    • 就我而言,我没有直接访问数据库的权限,但可以访问数据库中的表。在我的情况下,经纪人队列仍然有意义吗?我需要一种方法来轮询特定表的更改(插入、更新、删除),并触发一个事件作为结果,以便随后进行进一步处理。我考虑了一个 CLR 函数的想法,或者在成功插入/更新/删除表中的数据后调用服务的某种东西。在这种情况下还好吗?
    • 要编写 SQL-CLR,您需要直接访问数据库本身。其实你在自相矛盾?!
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        我思考了一个 CLR 函数的想法 或类似的东西 成功后的服务 插入/更新/删除数据 桌子。这还好吗 情况?

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

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

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

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

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

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

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

        希望这会有所帮助。

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

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

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

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

            【讨论】:

              猜你喜欢
              • 2011-03-22
              • 2022-12-17
              • 2017-12-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-06-03
              • 2020-10-28
              相关资源
              最近更新 更多