可替代轮询MSSQL表



我有一个MSSQL表,其中包含我的Windows服务应该根据时间戳处理的计划任务,我想知道除了像这样轮询表之外,我还有什么选择

SELECT *
FROM mydb
WHERE SYSUTCDATE() >= timestamp

我可能需要至少每5秒钟对表格进行一次轮询。基本上,我希望我的Windows服务在表中时间戳设置的时间处理数据。

对我来说,这似乎不是最有效的方法。我已经研究过DML&CLR触发器,我认为它们不会工作,因为它们会在数据更改时触发,而不是在时间戳经过时触发。想法?


更新2:

我意识到称之为"预定任务"是一个糟糕的措辞选择,所以我会尝试更详细地描述它。

这个项目的目标是根据我们的业务逻辑向人们发送电话通知。一种情况是,应该根据内部事件在特定时间给多个人打电话。同一个人可以被多次呼叫,这取决于电话的接听方式。因此,为了简化事情,消除管理每个电话状态的复杂性和开销,我认为将每个电话作为表中的一个条目来预先安排是一个好主意。当通知应该停止时,将从表中删除挂起的电话。这将使Windows服务的设计非常简单。它所要做的就是根据表中的时间戳发送通知。


更新1:

消息队列

我还没有弄清楚发件人将如何在适当的时间将消息放入队列。

SqlDependency

我在使用SqlDependency检测更改的示例代码时遇到问题。由于某些原因,OnChange事件最初只被触发,以后不会发生任何事情。

更新:我认为SqlDependency不会起作用,因为表中的数据不会更改以触发触发器。

void Initialization()
{
   // Create a dependency connection.
   SqlDependency.Start(connectionString, queueName);
}
void SomeMethod()
{
   // Assume connection is an open SqlConnection.
   // Create a new SqlCommand object.
   using (SqlCommand command=new SqlCommand(
      "SELECT timestamp,othercolumn FROM mydb WHERE SYSUTCDATE() >= timestamp", 
       connection))
   {
   // Create a dependency and associate it with the SqlCommand.
   SqlDependency dependency=new SqlDependency(command);
   // Maintain the refence in a class member.
   // Subscribe to the SqlDependency event.
   dependency.OnChange += new OnChangeEventHandler(OnDependencyChange);
   // Execute the command.
   using (SqlDataReader reader = command.ExecuteReader())
   {
      // Process the DataReader.
   }
}

好吧,首先,考虑根本不这么做。将所有有用的工作都推给数据库中配置的定期任务是一种脆弱的设计,当有人误解事情时,这种设计很容易崩溃(很容易做到,因为你需要非常高级的触发器来检查时间表的一致性),当任务实际上有隐藏的依赖关系时,它也倾向于创建一个令人费解的系统(如果a在B之前一段时间没有运行,那么东西就会坏掉,诸如此类)。来源:在三家不同的公司和三种不同的平台/技术中使用三个这样的系统的个人经历,不知何故,他们都遇到了同样的问题,所以显然这是一件事。考虑将您想要安排的事情写为普通的旧代码,并带有一个配置文件。当然,它不会那么通用,但必须维护它的人会感谢你,尤其是当他们的需求变得更加复杂时。

SqlDependency相当多变,即使您有一个支持的查询,也不容易很好地使用。在您的情况下,正如您所注意到的,它不起作用,因为除非数据实际发生更改,否则数据库引擎不会发布通知——查询结果会随着时间的推移而更改并不重要。正如Nick所指出的,每隔5秒轮询一次数据库通常是很好的。如果您已经在mydb.timestamp上创建了一个索引,则这会产生可忽略不计的负载(创建索引非常重要,因为每5秒执行一次表扫描不是可以的)。

唯一的反对意见是延迟:如果时间表的任何更新必须每5秒更新一次以上,那么轮询是不够的。在这种情况下,您可以使用Service Broker,并在发生更改时(可能是从触发器)向队列发布通知。事实上,SqlDependency使用了相同的方法,因此您可以在SELECT * FROM table上创建一个依赖项,以便在表中任何发生更改时获得通知,然后执行实际查询以获得所需内容(可能发现什么都没有)。不过,请注意:在不被多次快速更新或连接中断弄糊涂的情况下,正确地编写代码并不是一件小事,而且可能不值得这样做,而不是定期重新加载。

相关内容

  • 没有找到相关文章

最新更新