确认 EndDialog 后,启动器从未激活
Initiator never activated when acknowledged of EndDialog
我希望在我的 SSB 实现中遵循 Remus Rusanu 的对话回收技术。我为启动器队列编写了一些激活程序,以便从目标中钩回 EndDialog 消息并从已关闭的对话句柄中清除 Dialog table。
尽管如此,虽然EndDialog ack正确地到达了启动端,但没有触发激活,所以我的消息处理程序无法操作和清理这个地方。
CREATE PROCEDURE fdwh.ProcessResponse
AS
BEGIN
DECLARE @dlgId UNIQUEIDENTIFIER;
DECLARE @msgTypeName SYSNAME;
DECLARE @msgBody VARBINARY(MAX);
DECLARE @payloadHistoryId INT;
BEGIN TRY
BEGIN TRANSACTION
WAITFOR(
RECEIVE TOP(1)
@dlgId = [conversation_handle],
@msgTypeName = message_type_name,
@msgBody = message_body
FROM [fdwh].[SenderQueue]), TIMEOUT 10;
-- Message is regular end of conversation, terminate it
IF (@msgTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
BEGIN
END CONVERSATION @dlgId;
DELETE FROM DWH_BOARD.dbo.Dialog
WHERE (DbId = DB_ID()) AND
(DialogId = @dlgId);
END
-- Message is error, extracts and logs number and description
IF (@msgTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/Error')
BEGIN
[...]
我希望触发队列激活并处理 http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog 消息,但事实并非如此。 EndDialog ACK 不是常规消息吗?
请在下面找到自我解释的 Profiler 跟踪屏幕截图:。
示例是纯本地的(单个 instance/two 数据库)。
谢谢,
更新
失败队列的更多指标:
`SELECT que.[name], que.is_activation_enabled, que.is_receive_enabled, que.is_poison_message_handling_enabled, que.activation_procedure, que.max_readers, [execute_as] = (SELECT pri.[name] FROM sys.database_principals pri WHERE pri.principal_id = que.execute_as_principal_id) FROM sys.service_queues que WHERE que.[name] = 'SenderQueue' ;
开始
SELECT conversation_handle, to_service_name, message_type_name, is_conversation_error, is_end_of_dialog, enqueue_time, transmission_status 来自 sys.transmission_queue;
开始
SELECT [姓名], is_broker_enabled, log_reuse_wait_desc 来自 sys.databases WHERE database_id = 8;
开始
执行sp_spaceused'fdwh.SenderQueue';
开始
SELECT * 来自 sys.dm_broker_activated_tasks 其中 database_id=8;
开始
SELECT [state], last_activated_time, tasks_waiting FROM sys.dm_broker_queue_monitors WHERE database_id = 8;
走
`
仅当新消息到达时才会激活。
"When STATUS = ON, the queue starts the stored procedure specified
with PROCEDURE_NAME when the number of procedures currently running is
less than MAX_QUEUE_READERS and when messages arrive on the queue
faster than the stored procedures receive messages."
https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-queue-transact-sql?view=sql-server-2017
激活过程预计会继续使用消息,直到队列为空,并在其 WATFOR ... RECEIVE 期间保持为空。
您的激活程序缺少循环。它正在接收一条消息并退出。因此,每次新消息到达时,都会消耗一条旧消息。这可能 看起来 可以工作一段时间,但如果您遇到积压的消息,您将永远赶不上。
我希望在我的 SSB 实现中遵循 Remus Rusanu 的对话回收技术。我为启动器队列编写了一些激活程序,以便从目标中钩回 EndDialog 消息并从已关闭的对话句柄中清除 Dialog table。
尽管如此,虽然EndDialog ack正确地到达了启动端,但没有触发激活,所以我的消息处理程序无法操作和清理这个地方。
CREATE PROCEDURE fdwh.ProcessResponse
AS
BEGIN
DECLARE @dlgId UNIQUEIDENTIFIER;
DECLARE @msgTypeName SYSNAME;
DECLARE @msgBody VARBINARY(MAX);
DECLARE @payloadHistoryId INT;
BEGIN TRY
BEGIN TRANSACTION
WAITFOR(
RECEIVE TOP(1)
@dlgId = [conversation_handle],
@msgTypeName = message_type_name,
@msgBody = message_body
FROM [fdwh].[SenderQueue]), TIMEOUT 10;
-- Message is regular end of conversation, terminate it
IF (@msgTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
BEGIN
END CONVERSATION @dlgId;
DELETE FROM DWH_BOARD.dbo.Dialog
WHERE (DbId = DB_ID()) AND
(DialogId = @dlgId);
END
-- Message is error, extracts and logs number and description
IF (@msgTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/Error')
BEGIN
[...]
我希望触发队列激活并处理 http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog 消息,但事实并非如此。 EndDialog ACK 不是常规消息吗?
请在下面找到自我解释的 Profiler 跟踪屏幕截图:
示例是纯本地的(单个 instance/two 数据库)。
谢谢,
更新 失败队列的更多指标: `SELECT que.[name], que.is_activation_enabled, que.is_receive_enabled, que.is_poison_message_handling_enabled, que.activation_procedure, que.max_readers, [execute_as] = (SELECT pri.[name] FROM sys.database_principals pri WHERE pri.principal_id = que.execute_as_principal_id) FROM sys.service_queues que WHERE que.[name] = 'SenderQueue' ; 开始
SELECT conversation_handle, to_service_name, message_type_name, is_conversation_error, is_end_of_dialog, enqueue_time, transmission_status 来自 sys.transmission_queue; 开始
SELECT [姓名], is_broker_enabled, log_reuse_wait_desc 来自 sys.databases WHERE database_id = 8; 开始
执行sp_spaceused'fdwh.SenderQueue'; 开始
SELECT * 来自 sys.dm_broker_activated_tasks 其中 database_id=8; 开始
SELECT [state], last_activated_time, tasks_waiting FROM sys.dm_broker_queue_monitors WHERE database_id = 8; 走 `
仅当新消息到达时才会激活。
"When STATUS = ON, the queue starts the stored procedure specified with PROCEDURE_NAME when the number of procedures currently running is less than MAX_QUEUE_READERS and when messages arrive on the queue faster than the stored procedures receive messages."
https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-queue-transact-sql?view=sql-server-2017
激活过程预计会继续使用消息,直到队列为空,并在其 WATFOR ... RECEIVE 期间保持为空。
您的激活程序缺少循环。它正在接收一条消息并退出。因此,每次新消息到达时,都会消耗一条旧消息。这可能 看起来 可以工作一段时间,但如果您遇到积压的消息,您将永远赶不上。