I am using SQL server tables to act as a queue in my applications. Im using Query Notification using SQL Dependency, notably Jeremiah Gowdy's awesome implementation used in this blog post. http://jgowdy.blogspot.com/2010/01/sqldependency-query-notification-with.html
I implement this in a Windows Service and use it to "listen" to changes on a SQL Table i.e. my queue and do processing on the returned contents of the queue if theres a change - see code below, returns a dataset of the contents of the stored procedure.
The problem is, under heavy load or just over a period of time, changes are no longer detected, even though records exist in the table. When I restart the service the changes are then detected! Ive tried updating the table manually, to trigger a notification but to no avail. It seems like the notification service breaks at some point and fails to re-subscribe, but i cant be sure.
Im desperately trying to find a solution to this problem, as i have to constantly watch for changes in the tables themselves and restart the services if the queue gets stuck - not ideal!
Has anyone else had any issues with SQL Dependency and Query notification? Particularly any guidance on or knowledge on know issues would help. I know better queuing systems exist, but im trying to resolve this problem if i can rather than redevelop the entire project!!!
Here is a code snippet.
//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
}
Here is my stored procedure
Create PROCEDURE [dbo].[TransferExportQueue]
AS
BEGIN
SELECT [Id]
,[TransactionLogId]
,[QueueDate]
,[UpdateTable]
FROM [dbo].[TransferExportQueue]
END
UPDATE:
I have had a sql server logs and im getting the following errors.
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>'.
It seems that Remote service keeps dropping, after more digging, it seems that its got to do with how SQLDependency does its clean up of the subscriptions after every call. Does anyone know how to fix this issue?