SqlDependency订阅在关闭时未从dm_qn_subscriptions中删除

问题描述 投票:4回答:2

我的SqlDependency正常工作,并且当应用程序退出时,Broker队列和服务被正确删除(我建议在终止进程之前执行SqlDependency.Stop(...)),但是我请注意,在应用程序关闭后,由[[SqlDependency创建的通知订阅将保留在表“ sys.dm_qn_subscriptions”中。

如果稍后执行(应关闭应用程序后)执行应使此订阅激发的条件,则它似乎会触发,因为SQL Server在事件查看器中记录了一条Info消息,结果是:

对话柄上的查询通知对话框'{3F03B693-C0A5-E211-A97B-E06995EBDB20}.'由于以下原因而关闭错误:'<?xml version="1.0"?><Error xmlns="http://schemas.microsoft.com/SQL/ServiceBroker/Error"><Code>-8490</Code><Description>Cannot find the remote service &apos;SqlQueryNotificationService-0ea1f686-e554-4e25-aa7d-4f6d85171cc3&apos; because it does not exist.</Description></Error>'

然后将订阅从“ sys.dm_qn_subscriptions”中删除。

注意:当应用程序处于活动状态时,订阅也会正确触发。就我的应用程序而言,没有任何问题,但是令我担心的是,一旦终止它们依赖的代理队列/服务,订阅将不会在数据库系统表中自动擦除。这可能(至少)导致大量的幻像/不死订阅记录在数据库中累积,并导致Event Viewer中不必要的SQL Server清理消息(每个应用运行都会在“ sys.dm_qn_subscriptions”中生成新的不死记录)。

此行为正常吗?可以使事情整洁吗?

.net sql-server service-broker sqldependency event-viewer
2个回答
4
投票
这是正常行为。 QN寿命很长,它们将在数据库重新启动时触发(因此也将在服务器重新启动后触发)。但是,SqlDependency设置了一个临时服务/队列来接收通知,并且当发生崩溃时,应该使用dialog timerinternal activation将其拆除。这两种机制相互作用的方式就是您所看到的ERRORLOG污染。 [[B0]]没有任何事情发生,at least not usually,但显然不是很整洁。

可以使事情整洁吗?

您可以直接使用SqlNotificationRequest推出自己的解决方案,该解决方案不再提供创建服务/队列的“服务”来接收您的appdomain通知并将其路由到适当的SqlNotificationRequest事件。根据实际情况,有可行的替代方案。但是工作水平较低,与原始的SqlDependency.OnChange解决方案相比,您可能会以更糟糕的方式解决问题...

BTW无法在应用程序退出时“删除”待处理的QN订阅。问题是QN用作通知传递机制的单向对话框中固有的。正确的通知(订阅)应由订户启动,并且该通知应是从目标(通知者)返回到发起者(订户)的响应消息。


0
投票
© www.soinside.com 2019 - 2024. All rights reserved.