是否有扫描执行某些操作的作业表的标准模式?

时间:2010-03-13 01:33:02

标签: c# sql-server database algorithm

(我意识到我的头衔很差。如果在阅读完问题之后你会有所改进,请编辑或告诉我,我会改变它。)

我有一个相对常见的工作表场景,其中有一行需要完成。例如,它可以是要发送的电子邮件列表。该表看起来像这样:

ID    Completed    TimeCompleted   anything else...
----  ---------    -------------   ----------------
1     No                           blabla
2     No                           blabla
3     Yes          01:04:22
...

我正在寻找一个标准的练习/模式(或代码 - C#/ SQL Server首选)来定期“扫描”(我非常松散地使用术语“扫描”)这个表,找到未完成的项目,执行操作,然后在成功完成后将其标记为已完成。

除了完成上述步骤的基本过程外,我还在考虑以下要求:

  • 我想要一些“线性缩放”的方法,例如同时运行多个“工作进程”或线程或其他任何东西。 (只是一个特定的技术思想 - 我假设由于这个要求,我需要一些方法将项目标记为“正在进行中”以避免多次尝试该操作。)
  • 表格中的每个项目只能执行一次。

其他一些想法:

  • 我并不特别关心数据库中的实现(例如在T-SQL或PL / SQL代码中)与某些外部程序代码(例如独立的可执行文件或网页触发的某些操作)的关系。是针对数据库执行的
  • “做行动”部分是同步还是异步完成并不是我正在考虑作为这个问题的一部分。

3 个答案:

答案 0 :(得分:1)

为了扩展,您可能需要考虑扫描已准备好的作业,然后将它们添加到消息队列中。这样,多个消费者可以从队列中读取就绪作业。将作业标记为“正在进行”可能就像将该值放在“已完成”列中一样简单,或者您可以添加TimeStarted列并在作业重置之前具有预定的超时时间并且有资格让另一个工作线程处理。 (如果在没有完成作业的情况下经过一段时间,后一种方法假定处理失败。经过一些尝试后失败应该要求手动检查该作业。)扫描数据库以便准备好的作业添加到队列的同一个守护程序进程可以寻找已经超时的工作。

答案 1 :(得分:1)

如果您愿意考虑非数据库技术,那么最好的(但不是唯一的)解决方案是message queuing(通常与包含每个作业详细信息的数据库结合使用)。消息队列提供了许多功能,但基本工作流程很简单:

1)一个进程将“作业消息”(可能只是一个id)放在队列中。

2)另一个过程密切关注队列。它轮询队列中的工作,并按照收到的顺序从队列中一次一个地拉出队列。您从队列中取出的项目实际上标记为“正在进行中” - 它们不再可用于其他进程。

3)对于关键工作流,您可以执行事务性读取 - 在系统发生故障时,事务将回退并且消息仍在队列中。如果存在其他类型的异常(例如数据库读取期间的超时),您可能只是将消息转发到特殊的错误队列。

最简单的扩展方法是让读者进程调度多个线程来处理它从队列中取出的作业。或者,您可以使用多个读取器进程扩展,这些进程可能位于不同的服务器上。

.NET支持包括Microsoft Message Queue,以及Windows Communication Foundation或System.Messaging命名空间中的类。它需要一些设置和配置(你必须创建队列和配置权限),但它是值得的。

答案 2 :(得分:1)

如果您使用的是SQL 2005+,则可能需要调查Service Broker。它几乎是为此设计的。