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

时间:2019-04-02 19:21:33

标签: sql sql-server-2016 service-broker


我在数据库上启用了SQL Server 2016 Broker。我目前正在测试中,即使结束对话后,我也无法清除sys.conversation_groups表。我应该为此担心吗?我很难理解这张表在所有这些方面的作用。

请注意,我正在从“我的请求”队列发送消息到“发件人”。这是不好的做法吗?我不需要答案。我在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;

我在这里做错什么了吗?

1 个答案:

答案 0 :(得分:1)

好的,所以我认为我的问题是由“失火”模式引起的。但是对于我的应用程序,这确实是我们需要的模式。 (我们不处理任何错误。)此外,我们有一个威胁这些消息的服务,如果该服务被停止,它将重新初始化自身,并且不需要在服务停止时生成的消息。

因此,为了摆脱会话保持在“对话”状态的问题,我修改了发送消息的过程,以使消息的生存期延长2分钟。

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

这样,如果服务启动,它将读取消息并结束对话,即使对话保持“正在对话”状态,两分钟后它也会消失。而且,如果该服务已关闭,则它在恢复后将不会阅读旧邮件。