Web服务中的侦听事件或基于数据库的API发生更改

时间:2013-10-16 21:11:14

标签: c# sql web listeners

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

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

机器人定期检查数据库中的新行,检索数据并为该行设置某种标记,表明数据已被处理。

所以这里的主要问题是,proccessData(..)方法应该做什么来检查数据行的变化?

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

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

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

2 个答案:

答案 0 :(得分:0)

根据您对此分布式系统的设计有多少控制权,如果您退后一步并尝试在解决方案领域之外进行思考,那么对于其架构可能会更好。您已经确定了“主要问题”,即找到分布式服务通过公共数据库相互通信的方法。也许这是一个你应该挑战的想法。

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

如果在此考虑之后您的答案保持不变并且您确实需要立即通知,请考虑让处理工作项的组件通知需要通知的组件。作为分布式系统的一般设计原则,最好让对给定数据集最具权威性的组件也是回答有关该数据的请求的组件。在这种情况下,您拥有的数据是工作项的完成状态,因此对此采取行动的最佳组件是完成工作项的组件。该组件可能更好地通知调用客户端和组件完成。此处,了解您是否仅将这些数据写入数据库以便在组件之间进行通信,或者这些行是否具有超出给定工作项完成的任何值(例如,用于报告目的或性能指标(KPI)),这一点也很重要。

我认为可能有正当理由,为什么您不希望进行此类调用,例如减少组件之间的耦合或缺乏以直接方式与其他组件通信的访问权限。有许多允许此类通知的通信原语,例如Windows下的MSMQ或Windows Azure中的队列。还有一些原因可以解决这个问题,例如在系统内部依赖第三个组件进行通信,这可能会降低系统的可用性并导致中断。你可能想在这里问自己的问题是:“当它周围的一切都发生故障时,我的组件可以做多少工作?”和“在可靠性和可用性方面,我的设计优先考虑的是什么?”

所以我认为你可能想要真正尝试解决的主要问题有点抽象:这个分布式系统组件的通信接口应该如何通信?

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

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

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

答案 1 :(得分:0)

您指的是 Message Queue 吗? .Net框架已经提供了这种功能。我想说让Web服务管理一个应用程序级队列。机器人将为要做的事情请求相同的Web服务。假设作业所需的数据很小,您可以将整个内容保留在内存中。如果您还没有数据库,我宁愿不涉及数据库。