c# - 通过数据库更改监听Web服务或API中的事件

标签 c# sql web listeners

我有这种情况,我真的不知道从哪里开始。假设服务器上托管了一个类似Web服务的应用程序(可能是API tho)。该应用程序收到处理某些数据的请求(通过某种方法,我们将其称为processData(data theData))。

另一方面,有一个机器人(可能安装在同一服务器上)来处理数据。因此,Web服务将请求插入到公共数据库中(两个程序都可以访问它),并且应该等待该行更改并将结果发送回去。

机械手会定期检查数据库中是否有新行,处理数据并在该行中设置某种标志,以指示数据已处理。

因此,这里的主要问题是,proccessData(..)方法应如何检查数据行的更改?

我知道一种实现方法:我可以构建一个迭代块,每隔x秒检查一次行。但是我不想那样做。我想要做的是构建某种事件侦听器,该侦听器在行更改时触发。我知道这可能涉及一些异步编程

我可能在做梦,但是在网络环境中甚至有可能吗?

我一直在阅读有关SqlDependency类,Async和AWait类等的信息。

最佳答案

取决于您对该分布式系统的设计有多少控制权,如果您退后一步并尝试在解决方案的范围之外进行思考,则可以将问题缩小到目前为止。您已经确定“主要问题”是在寻找一种分布式服务通过公用数据库相互通信的方法。也许这是您应该挑战的想法。

这些组件有许多潜在的通信方式,如果您的设计目标是减少延迟并避免轮询,那么实际上可能是正确的方法,需要通知服务此工作项的完成情况。它马上。但是,如果将来必须提高该系统的吞吐量,则批量处理工作项并轮询信息可能会成为唯一可行的选择。这也是为什么我选择更通用地表达我的答案,并更抽象地讨论此分布式系统的设计的原因。

如果经过此考虑,您的答案仍然是相同的,并且您确实希望立即通知,请考虑让组件处理工作项以通知需要通知的组件。作为分布式系统的一般设计原则,最好使对给定数据集最具权威性的组件也成为回答有关该数据请求的组件。在这种情况下,您拥有的数据是工作项的完成状态,因此,要执行此操作的最佳组件将是完成工作项的组件。该组件最好将完成的情况告知呼叫客户和组件。在这里,重要的是要知道是否仅出于组件之间的通信目的而将此数据写入数据库,或者这些行是否具有超出给定工作项完成的任何值,例如用于报告目的或性能指标(KPI)。

但是,我认为可能有正当的理由,为什么您不想打这样的电话,例如减少组件之间的耦合或缺少直接与其他组件进行通信的权限。有许多允许这种通知的通信原语,例如Windows下的MSMQ或Windows Azure中的队列。也有反对的理由,例如,依赖于系统内部通信的第三个组件,这可能会降低系统的可用性并导致中断。您在这里可能要问自己的问题是:“当周围的所有组件掉下来时,我的组件可以做多少工作?”和“就可靠性和可用性而言,我对该系统的设计重点是什么?”

因此,我认为您可能真正想解决的主要问题有点抽象:该分布式系统的组件之间进行通信的接口应该是什么样的?

如果在所有这些之后仍将这些组件之间的通信接口设置为SQL数据库,则可以探索在SQL中使用INSERT和UPDATE触发器。您可以轻松地查找这些命令的语法,并指定随后执行的存储过程。在这些存储过程中,您可能希望检查任何新行的完成标志,并可能按日期限制检查的行数,或者具有最后处理的工作项的ID。然后,要通知其他组件,您可以使用内置存储过程XP_cmdshell在Windows下执行命令行。您执行的命令可能是一个简单的工具,可以对您的服务执行ping操作以完成任务。

很抱歉最初忽略了您关于使用SQL查询通知的建议。这也是可行的方法,并且可以通过Service Broker组件进行工作。您将定义一个SqlCommand,就像通常查询数据库一样,将其传递给SqlDependency的实例,然后订阅名为OnChange的事件。一旦执行了SqlCommand,就应该调用添加到OnChange的事件处理程序。

但是,我不确定如何从将传递给事件处理程序的SqlNotificationEventArgs对象中获取对数据库的确切更改,因此您的查询可能需要足够具体,以使应用程序能够知道工作项查询更改时,操作已经完成,或者您可能每次需要通知您才能知道更改的确切时间时,都必须从应用程序对数据库进行另一次往返。

关于c# - 通过数据库更改监听Web服务或API中的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19413974/

相关文章:

C#:如何将特殊字符写入 ADLDS?

php - 面临将值放入聊天页面 php 的问题

iis-7 - 在ISAPI筛选器上调用LoadLibraryEx

permissions - 拒绝访问文件夹但不访问其中的文件

c# - "this"关键字可以与值类型一起使用吗?

c# - 真假值的字符串比较 OrdinalIgnoreCase

c# - 如何使用正则表达式在 C# 中获取字符串的一部分

mysql - 使用 CONCAT 函数添加到 mysql 列中的现有值?

mysql - 有没有办法在 MySQL 中为每个数据库设置密码?

php - 如何正确保护 api key ?