2

我有一个在多个 IIS6 Web 服务器上运行的 ASP.NET 应用程序,带有一个 SQL Server 2005 数据库后端。

我需要:

  1. 监视数据库以完成外部作业事件,然后

  2. 让一个 Web 应用程序实例向 Web 服务提交一些信息

对于(1),似乎 SqlDependency 是最好的方法(或者只是普通的旧轮询)。每个 Web 应用程序实例在启动时都会注册这样的依赖项。(我不想配置“主”实例,因为该实例的失败将意味着任务不会继续,即使其他实例可用。因此我的设计是确保如果有可用的实例工作,那么工作应该继续进行。)

对于 (2),我一直在考虑在数据库中设置某种标志,Web 应用程序实例在收到 (1) 中的 SqlDependency 通知后会尝试更新,如下所示(非常简化):

UPDATE StatusTable SET TaskStatus = 1 WHERE TaskStatus = 0

SELECT @@ROWCOUNT

这个想法是只有一个应用程序实例能够更新TaskStatus,因此只有一个实例的@@ROWCOUNT > 0。这将是“选择”将信息提交给Web服务的实例。

这种方法有哪些不足之处?我还有哪些其他选择?(注意:不能选择单独的服务来完成这项工作。)

4

1 回答 1

1

全局“标志”不起作用,请记住,您有多个服务员多个通知,您不希望一个“服务员”接收所有通知。要可靠地选择“恰好一个”任务,请将 UPDATE 与 OUTPUT 一起使用:

UPDATE TOP(1) StatusTable
   SET Status = 1
OUTPUT DELETED.TaskId
WHERE Status = 0;

这是从用作队列的表中取出行的推荐的可靠方法,请参阅OUTPUT 子句中的队列段落。

但是现在您应该意识到 1) 您将表用作队列 2) 您正在接收来自这些队列的通知 3) 您使用 Service Broker 来传递这些通知(通过内部使用 Service Broker的 SqlDependency )。那么为什么不只使用普通的 Service Broker 呢?您需要一个队列和一个服务,并让每个实例在此队列上启动一个WAITFOR(RECEIVE...) (不是轮询)。感兴趣的工作以SEND结束其工作到您的服务,通知工作已完成。正是您的一个实例将接收此通知并进行后处理(即传递 Web 服务调用)。这样,您就可以消除通知周围的所有“绒毛”(SqlDependency、全局标志、用作队列的表),并且您违背了 SqlDependency 无论如何都会使用的准系统基础设施。

于 2010-03-05T00:17:09.440 回答