【问题标题】:Query Notification using Sql Dependency - Stops detecting changes使用 Sql Dependency 查询通知 - 停止检测更改
【发布时间】:2014-04-01 11:47:37
【问题描述】:

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

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

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

我正在拼命寻找这个问题的解决方案,因为我必须不断观察表本身的变化并在队列卡住时重新启动服务 - 不理想!

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

这是一个代码 sn-p。

//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 如何在每次调用后清理订阅有关。有谁知道如何解决这个问题?

【问题讨论】:

  • 你只有一个初始化吗?如果没有,那么有多少?
  • 您的意思是“SqlQueueWatcher”实例?我有一个包含 SqlQueueWatcher 基本代码的 Common 类,我的解决方案中的其他几个项目都以此实例化(大约 8 个项目)。
  • 检查你初始化的实例是否多于数据库中的池连接数
  • 谢谢 rudym,我会检查一下,如果池连接用完不应该抛出错误吗?
  • 不会抛出错误。尝试像这样检查池连接 [support.microsoft.com/kb/815158/EN-US]

标签: c# sql-server service-broker sqldependency query-notifications


【解决方案1】:

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

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

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

【讨论】:

  • 谢谢 Remus,我只是在阅读您处理我的确切问题的帖子!所以没有办法解决这个问题吗?问题是应用程序是实时部署的,这个问题只是在负载测试下才真正出现!如果没有我有一些编码要做......
  • 我只能说享受你的编码:(如果还没有现场事件,你将有时间正确设计它。
  • 谢谢 Remus,是的,我很害怕。战场。
  • 你有什么好的例子说明如何实现SqlNOtificationRequest,好像很少!我看过这里,msdn.microsoft.com/en-us/library/3ht3391b(v=vs.80).aspx,但它有问题,似乎没有按预期工作。有什么资源可以指点我吗?
  • @RemusRusanu 感谢您的出色回答。那么你是说如果你使用 SqlDependency 那么它会在后台管理所有服务代理的东西吗?谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多