2

我正在使用 SQL Server 表在我的应用程序中充当队列。我使用 SQL Dependency 的查询通知,特别是 Jeremiah Gowdy 在这篇博文中使用的很棒的实现。http://jgowdy.blogspot.com/2010/01/sqldependency-query-notification-with.html

我在 Windows 服务中实现了这一点,并使用它来“监听”SQL 表(即我的队列)上的更改,如果有更改,则对队列的返回内容进行处理 - 请参见下面的代码,返回内容的数据集存储过程。

问题是,在重负载下或仅经过一段时间后,即使表中存在记录,也不再检测到更改。当我重新启动服务时,就会检测到更改!我尝试手动更新表格以触发通知但无济于事。通知服务似乎在某些时候中断并且无法重新订阅,但我不能确定。

我拼命地试图找到解决这个问题的方法,因为我必须不断地观察表本身的变化,如果队列卡住,我会重新启动服务——不理想!

还有其他人对 SQL 依赖和查询通知有任何问题吗?特别是任何关于已知问题的指导或知识都会有所帮助。我知道存在更好的排队系统,但如果可以的话,我会尝试解决这个问题,而不是重新开发整个项目!!!

这是一个代码片段。

//Initialisation
public void StartWatcher()
{
    SqlCommand cmd = new SqlCommand();
    cmd = new SqlCommand("TransferExportQueue");
    cmd.CommandType = System.Data.CommandType.StoredProcedure;

    log.Info("Setting up SQL Watcher");
    //Setup the SQLWatcher
    SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
    builder.ConnectionString = ConfigurationManager.ConnectionStrings["Connexion"].ConnectionString;

    log.Info("Attempting to Start");
    SqlQueueWatcher = new SqlWatcher(builder.ConnectionString, cmd, SqlWatcher.SqlWatcherNotificationType.Blocking);
    SqlQueueWatcher.OnChange += new SqlWatcher.SqlWatcherEventHandler(QueueSQLWatcher_OnChange);
    SqlQueueWatcher.Start();

}

//OnChangeEvent
private void QueueSQLWatcher_OnChange(DataSet Result)
{
    //perform logic in returned contents of stored procedure
}

这是我的存储过程

Create PROCEDURE [dbo].[TransferExportQueue] 
AS
BEGIN

SELECT [Id]
      ,[TransactionLogId]
      ,[QueueDate]
      ,[UpdateTable]
FROM [dbo].[TransferExportQueue]



END

更新: 我有一个 sql server 日志并且我收到以下错误。

The query notification dialog on conversation handle '{9586CB6A-62BA-E311-983B-A0369F0A65D3}.' closed due to the following error: '<?xml version="1.0"?><Error xmlns="http://schemas.microsoft.com/SQL/ServiceBroker/Error"><Code>-8470</Code><Description>Remote service has been dropped.</Description></Error>'.

似乎远程服务不断下降,经过更多挖掘,似乎与 SQLDependency 在每次调用后如何清理订阅有关。有谁知道如何解决这个问题?

4

1 回答 1

3

阅读这篇文章:SqlDependency.OnChange 回调时机。它的要点是您的应用程序有有限的时间来处理 OnChange 回调,否则激活的过程计时器将启动并终止服务,从而对您的应用程序造成严重破坏。就我个人而言,我不是这个设计的粉丝,但它就是这样。

欢迎加入那些不得不放弃方便SqlDependency使用的人的俱乐部,它是即时部署的基础设施,并使用更基本的SqlNotificationRequest类,这需要您明确地部署目标服务/队列。您在易用性方面所松懈的东西,您将获得对行为的控制权,如果您最终从正在运行的应用程序中删除目标服务,至少您只能责怪自己;)

不过说真的,从 SqlDependency 切换到 SqlNotificationRequest 相当容易,我推荐它。

于 2014-04-02T12:59:33.197 回答