SQL 队列停止工作并填满消息

标签 sql notifications queue broker

目前我正在为 SQL 代理而苦苦挣扎。一切似乎都配置良好,但队列停止工作并填满未发送的消息。代理和队列已启用。如果我删除队列和服务并重新创建它们,它会工作一段时间但稍后会再次停止。我在 sql server 日志中没有看到任何重要错误。那么什么会导致错误呢?

谢谢

排队

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();
    }

最佳答案

当队列“停止”时它是否仍然启用?

如果不是,您可能正在处理 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;

关于SQL 队列停止工作并填满消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8848224/

相关文章:

c++ - front() 和 back() 在队列中分配值的目的? (C++)

java - 来自 java jdbc 连接的架构名称 Sql 服务器

sql - 在一个连接表上使用组合条件连接

email - 新产品到达 magento 时自动向客户发送邮件提醒

c++ - 使用 ReadDirectoryChangesW 是否需要管理员权限?

java - PendingIntent.getBroadcast 不适用于通知抽屉中的默认通知单击/触摸事件 - Android Studio 2.3.3 + Java

java - 跟踪队列中的值变化 - java

Python 多处理控制的双向队列

sql - 聚合函数中的 Null

sql - 或者在 Postgres 中没有按预期工作