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"状态,也会在两分钟后消失。如果服务中断,它在恢复后将不会读取旧消息。
我在数据库上启用了 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"状态,也会在两分钟后消失。如果服务中断,它在恢复后将不会读取旧消息。