【问题标题】:Sql Server Service BrokerSql Server 服务代理
【发布时间】:2011-09-20 00:56:14
【问题描述】:

目前我们正在使用服务代理来回发送消息,这工作正常。但我们想使用 RELATED_CONVERSATION_GROUP 对这些消息进行分组。我们想使用我们自己的数据库持久化 uuid 作为数据库中的 RELATED_CONVERSATION_GROUP = @uuid,但即使每次收到队列时,每次转换组 ID 都不同时,我们使用相同的 uuid。

你们知道我创建代理或接收呼叫的方式有什么问题吗,我在下面提供了代理创建代码和接收呼叫代码。谢谢

下面是代码“Service Broker 创建代码”

CREATE PROCEDURE dbo.OnDataInserted

@EntityType NVARCHAR(100),
@MessageID BIGINT,
@uuid uniqueidentifier,
@message_body nvarchar(max)
AS

BEGIN

SET NOCOUNT ON;

 DECLARE @conversation UNIQUEIDENTIFIER

BEGIN DIALOG CONVERSATION @conversation
FROM SERVICE DataInsertSndService
TO SERVICE 'DataInsertRcvService'
ON CONTRACT DataInsertContract
WITH RELATED_CONVERSATION_GROUP = @uuid;

SEND ON CONVERSATION @conversation
MESSAGE TYPE DataInserted
(CAST(@message_body))

下面是代码“接收代码”

WHILE 0 < @@TRANCOUNT ROLLBACK; SET NOCOUNT ON

BEGIN TRANSACTION;

DECLARE 
@cID as uniqueidentifier, 
@conversationHandle as uniqueidentifier,
@conversationGroupId as uniqueidentifier,
@tempConversationGroupId as uniqueidentifier,
@message_body VARBINARY(MAX)

RAISERROR ('Awaiting Message ...', 16, 1) WITH NOWAIT

;WAITFOR (RECEIVE TOP (1) 
@cID = Substring(CAST(message_body as nvarchar(max)),4,36), 
@conversationHandle = [conversation_handle],
@conversationGroupId = [conversation_group_id],
@message_body = message_body
FROM DataInsertRcvQueue)

RAISERROR ('Message Received', 16, 1) WITH NOWAIT
Select @tempConversationGroupId = conversationGroupID from ConversationGroupMapper where cID = @cID; 
declare @temp as nvarchar(max);
Set @temp = CAST(@tempConversationGroupId as nvarchar(max));
if @temp  <> ''
BEGIN
    MOVE CONVERSATION @conversationHandle TO @tempConversationGroupId;

RAISERROR ('Moved to Existing Conversation Group' , 16, 1) WITH NOWAIT
END
    else
BEGIN
insert into ConversationGroupMapper values (@cID,@conversationGroupId);

RAISERROR ('New Conversation Group' , 16, 1) WITH NOWAIT
END

WAITFOR DELAY '000:00:10'

COMMIT

RAISERROR ('Committed' , 16, 1) WITH NOWAIT

阐述

我们的情况是,我们需要循环接收来自该 Service Broker 队列的项目,在 WAITFOR 上阻塞,然后通过不可靠的网络将它们交给另一个系统。从队列中接收到的项目的目的地是与该远程系统的许多连接之一。如果该项目未成功交付到其他系统,则应回滚该单个项目的事务并将该项目返回到队列中。我们在成功交付后提交事务,解锁要由后续循环迭代拾取的消息序列。

相关项目序列的延迟不应影响不相关序列的交付。单个项目一旦可用就会立即发送到队列中并立即转发。项目应该以单个文件的形式转发,尽管即使在一个序列中的交付顺序也不是很重要。

从一次接收一条消息的循环中,从我们的打开连接列表中选择一个新的或现有的 TcpClient,然后将消息和打开的连接通过异步 IO 回调链传递,直到传输完成.然后我们完成从 Service Broker Queue 接收到 Item 的 DB Transaction。

在这种情况下如何使用 Service Broker 和对话组来提供帮助?

【问题讨论】:

    标签: sql sql-server database service-broker


    【解决方案1】:

    对话组只是一个本地概念,专门用于锁定:相关对话属于一个组,因此当您在一个对话上处理消息时,另一个线程无法处理相关消息。没有关于两个端点交换的对话组的信息,因此在您的示例中,所有发起者端点最终都属于一个对话组,但目标端点都是一个不同的对话组(每个组只有一个对话)。系统之所以如此,是因为对话组旨在解决诸如旅行预订服务之类的问题:当它收到“预订旅行”的消息时,它必须预订航班、酒店和汽车出租。它必须发送三个消息,每个服务('flights'、'hotels'、'cars')发送一条消息,然后响应将异步返回。当它们确实返回时,处理必须确保它们不会被单独的线程同时处理,每个线程都会尝试更新“旅行”记录状态。在消息传递中,这个问题被称为“消息关联问题”。

    但是,会话组通常仅出于性能原因而部署在 SSB 中:它们允许更大的 RECEIVE 结果。使用MOVE CONVERSATION 可以将目标端点一起移动到一个组中,但实际上有一个更简单的技巧:反转对话的方向。让您的目的地开始对话(分组),来源发送关于由目的地开始的对话的“更新”。

    一些注意事项:

    • 不要使用 BEGIN/SEND/END 的即发即弃模式。您使将来无法诊断任何问题,请参阅Fire and Forget: Good for the military, but not for Service Broker conversations
    • 永远不要在生产代码中使用 WITH CLEANUP。它旨在用于管理上的最后手段,例如灾难恢复。如果您滥用它,您将拒绝 SSB 任何机会正确跟踪消息以正确重试传递(如果消息在目标上反弹,无论出于何种原因,它将永远丢失)。
    • SSB 不保证会话之间的顺序,只保证一个会话中的顺序。为每个 INSERT 事件启动新对话并不能保证在目标上保留插入操作的顺序。

    【讨论】:

    • 感谢您。这些是很好的链接和解释,但我们仍然感到困惑。 Gopi 在原帖中添加了一些细节。我们通过保留嵌入在项目消息正文中的内部 ID 到对话组 ID 的映射来尝试 MOVE CONVERSATION。如果一个 Item 带有尚未在地图中的新内部 ID,我们添加它,否则我们将 MOVE CONVERSATION 移动到找到的会话组 ID 项目。不幸的是,这实际上不允许后续接收(当会话组的第一个事务处于活动状态时)跳到“非锁定”项目。
    • 感谢您的快速回复,我们尝试了您建议的“移动对话”选项,但仍然无法将所有内容放在一起。
    • ...我们不确定如何应用您关于让接收方发起对话的建议。也许如果我们使用其他渠道(如共享表)将对话 ID 或组 ID 传达给发送者,则可能在本地场景中工作,但即便如此,也不确定这是否有助于解决 Gopi 添加的场景。有什么想法吗?
    • 另外,您说“当您在一个对话中处理消息时,另一个线程无法处理相关消息”,但这听起来像是收件人会做的事情 - 处理消息。这听起来正是我们想要的,但你的描述的其余部分似乎检查了这个希望。 (如果我们在您的解释中遗漏了一个关键点,请原谅我们 - 我们已经阅读了很多次,并且正在尽最大努力正确地阅读它。)
    • 嗨@Remus Rusanu,对此有什么想法吗?这里没有进展。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    • 2019-11-06
    相关资源
    最近更新 更多