SQL Broker sys.conversation_groups 对话结束后不清空

SQL Broker sys.conversation_groups not emptying after conversation is ended


我在数据库上启用了 SQL Server 2016 Broker。我目前正在测试,我发现 sys.conversation_groups table 即使在我结束对话后也没有清理。我应该为此担心吗?我很难理解 table 在这一切中的作用。

请注意,我正在向我的请求队列发送消息和发送消息。这是一种不好的做法吗?我不需要答案。我在我的 C# 应用程序中阅读了消息,然后结束了对话。

这是我的设置:

CREATE MESSAGE TYPE SomeMessageType VALIDATION=NONE;
CREATE MESSAGE TYPE SomeReplyType VALIDATION=NONE; 

CREATE CONTRACT MyMessageContract
(
 SomeMessageType SENT BY INITIATOR 
,SomeReplyType SENT BY TARGET 
);

CREATE QUEUE MyBrokerRequestsQueue

CREATE SERVICE BrokerRequestsServices
ON QUEUE MyBrokerRequestsQueue (MyMessageContract); 

然后,我这样发送消息(仍然在我的测试服务器上,将在测试完成后由触发器发送):

declare @count int;
set @count = 1;

declare @msg nvarchar(max);
set @msg = 'This is a test ';

while (@count <= 100)
begin
    DECLARE @handle UNIQUEIDENTIFIER;

    BEGIN DIALOG @handle
      FROM SERVICE BrokerRequestsServices
      TO SERVICE 'BrokerRequestsServices'
      ON CONTRACT MyMessageContract
      WITH ENCRYPTION = ON;

      set @msg = 'This is a test ' + convert(nvarchar(3), @count);

      SEND ON CONVERSATION @handle MESSAGE TYPE SomeMessageType  ( @msg );

      set @count = @count + 1
end

C# 程序以这种方式读取队列:

string SQL = string.Format(@"
        waitfor( 
            RECEIVE top (@count) conversation_handle,service_name,message_type_name,message_body,message_sequence_number 
            FROM [{0}] 
                ), timeout @timeout", queueName);
  SqlCommand cmd = new SqlCommand(SQL, con);

  SqlParameter pCount = cmd.Parameters.Add("@count", SqlDbType.Int);
  pCount.Value = maxMessages;

  SqlParameter pTimeout = cmd.Parameters.Add("@timeout", SqlDbType.Int);

  if (timeout == TimeSpan.MaxValue)
  {
    pTimeout.Value = -1;
  }
  else
  {
    pTimeout.Value = (int)timeout.TotalMilliseconds;
  }

  cmd.CommandTimeout = 0; //honor the RECIEVE timeout, whatever it is.


  return cmd.ExecuteReader();

然后当它收到一条消息时,读取​​对话句柄并结束它。

END CONVERSATION @ConversationHandle;

我是不是做错了什么?

好的,所以我认为我的问题是由 "fire and forget" 模式引起的。但就我的应用程序而言,这确实是我们需要的模式。 (我们不处理任何错误。)此外,我们有一个威胁这些消息的服务,如果服务停止,它会重新初始化自己并且不需要在它关闭时生成的消息。

所以为了解决会话停留在Conversing状态的问题,我修改了发送消息的流程,增加了2分钟的消息生命周期。

BEGIN DIALOG @handle
FROM SERVICE BrokerRequestsServices
TO SERVICE 'BrokerRequestsServices'
ON CONTRACT MyMessageContract
WITH ENCRYPTION = ON, LIFETIME = 120;

这样,如果服务启动了,它会读取消息并结束对话,即使对话停留在"Conversing"状态,也会在两分钟后消失。如果服务中断,它在恢复后将不会读取旧消息。