【发布时间】: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