2012-01-13 44 views
3

當前我正在與SQL代理商苦苦掙扎。一切似乎都已配置好,但隊列停止工作,並填充未發送的消息。代理和隊列已啓用。如果我放棄隊列和服務並重新創建它們,它會運行一段時間,但稍後會再次停止。我在sql服務器日誌中沒有看到任何重要的錯誤。那麼,什麼會導致錯誤?SQL隊列停止工作,並填充消息

感謝

隊列

CREATE QUEUE [dbo].[DataChangeQueue] WITH STATUS = ON , RETENTION = OFF , ACTIVATION ( STATUS = ON , PROCEDURE_NAME = [dbo].[DataChangeQueueProc] , MAX_QUEUE_READERS = 100 , EXECUTE AS N'dbo'), POISON_MESSAGE_HANDLING (STATUS = ON) ON [PRIMARY] 

服務

CREATE SERVICE [DataChangeService] AUTHORIZATION [dbo] ON QUEUE [dbo].[DataChangeQueue] ([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification]) 

C#

public DatabaseNotificationService() 
    { 
     SqlDependency.Start(m_SQLConnectionString, "DataChangeQueue"); 

     if (IsAccessGranted()) 
     { 
      ConnectToDatabase(); 
     } 
    } 

    ~DatabaseNotificationService() 
    { 
     SqlDependency.Stop(m_SQLConnectionString, "DataChangeQueue"); 
    } 


    private void ConnectToDatabase() 
    { 
     using (SqlConnection sqlConnection = new SqlConnection(m_SQLConnectionString)) 
     { 
      sqlConnection.Open(); 

      using (SqlCommand sqlCommand = sqlConnection.CreateCommand()) 
      { 
       sqlCommand.CommandType = CommandType.Text; 
       sqlCommand.CommandText = GetSQLCommandText(); 
       sqlCommand.Notification = null; 

       if (m_SQLDependency != null) 
       { 
        m_SQLDependency.OnChange -= DependencyOnChange; 
        m_SQLDependency = null; 
       } 

       m_SQLDependency = new SqlDependency(sqlCommand, "Service=DataChangeService;Local Database=aspnetdb", 1800); 
       m_SQLDependency.OnChange += DependencyOnChange; 

       sqlCommand.ExecuteReader(); 
      } 

      sqlConnection.Close(); 
     } 
    } 


    private void DependencyOnChange(object sender, SqlNotificationEventArgs e) 
    { 
     using (SqlConnection sqlConnection = new SqlConnection(m_SQLConnectionString)) 
     { 
      sqlConnection.Open(); 

      using (SqlCommand cmd2 = sqlConnection.CreateCommand()) 
      { 
       cmd2.CommandType = CommandType.Text; 
       cmd2.CommandText = GetOnChangeSQLCommandText(); 

       using (SqlDataReader sqlDataReader = cmd2.ExecuteReader()) 
       { 
        if (sqlDataReader != null) 
        { 
         sqlDataReader.Read(); 

         List<String> keys = new List<String>(m_Clients.Keys); 
         foreach (String key in keys) 
         { 
          IDatabaseNotificationCallbackContract client; 
          if (m_Clients.TryGetValue(key, out client)) 
          { 
           if (((ICommunicationObject)client).State == CommunicationState.Opened) 
           { 
            client.SendNotificationToClients(sqlDataReader.GetValue(0).ToString()); 
           } 
           else 
           { 
            m_Clients.Remove(key); 
           } 
          }      
         } 
        } 
       } 
      } 

      sqlConnection.Close(); 
     } 

     if (m_SQLDependency != null) 
     { 
      m_SQLDependency.OnChange -= DependencyOnChange; 
      m_SQLDependency = null; 
     } 

     //Reconnect to database for listening to following changes. 
     ConnectToDatabase(); 
    } 
+0

你解決這個 - 我有一個類似的問題 – 2012-04-24 10:46:58

+0

我也是有類似的問題 - 這方面的更新? – lehn0058 2013-07-11 18:19:55

回答

0

當隊列的 「停止」 時仍然啓用?

如果不是,您可能會在隊列中處理poison message。他們可以停止處理

我建議檢查第一條消息,看看它是否對您的處理有效。

如果不是,則將其彈出。

下面是代碼,我會用刪除的第一次談話(因此帶毒郵件)關閉消息隊列的:

BEGIN TRANSACTION; 

DECLARE @handle nvarchar(100); 
RECEIVE TOP(1) @handle = [conversation_handle] FROM yourQueueName; 

END CONVERSATION (@handle) 
    WITH ERROR = 127 DESCRIPTION = N'Unable to process message.' ; 
GO 

COMMIT TRANSACTION;