Azure 服务总线 - 发布到队列和事务范围内的主题

Posted

技术标签:

【中文标题】Azure 服务总线 - 发布到队列和事务范围内的主题【英文标题】:Azure service bus - Post to a queue and a topic inside transaction scope 【发布时间】:2021-11-17 23:50:01 【问题描述】:

我有一个具有 ServiceBusTrigger Azure 函数的应用程序。在这个函数的处理程序中,当我在“QueueA”中收到队列消息后,我需要做一些业务逻辑,最后,我必须这样做:

将消息发布到另一个系统将使用的“TopicA” 向我的“QueueB”发布另一种消息,“QueueB”会将内容保存到数据库,更新我的活动状态 在文件共享存储中将文件从一个文件夹移动到另一个文件夹 将“QueueA”中收到的消息内容保存到数据库中

我需要在Transaction Scope 中完成所有这些工作,因为如果一项失败,其他任何一项都无法继续。

没有第二项,我的 cenário 工作得很好,因此在我尝试发布到同一事务中的主题和队列后,我收到了以下错误消息:

“本地事务不能跨越多个***实体,例如队列或主题。”

来自Microsoft's documentation 我发现了这个:

服务总线支持在事务范围内针对 SINGLE 消息传递实体(队列、主题、订阅)进行分组操作。例如,您可以在一个事务范围内向一个队列发送多条消息,只有在事务成功完成后,这些消息才会提交到队列的日志中。

我只是被困在这里,不知道我该怎么做才能保证线程安全。任何人都通过它并且可以帮助我发布到事务范围内的队列和主题?

【问题讨论】:

【参考方案1】:

TL;DR:您可以使用 Azure 服务总线使用最多 100 条消息的跨实体事务 API 发送/发布到多个目标。

事务处理、事务范围和 Azure 服务总线跨实体事务尽管有“事务”一词,但并不完全相同。

我需要在事务范围内完成所有这些工作,因为如果一项失败,其他任何一项都无法继续。

在 Azure 中,不存在跨越多个资源/服务并在发生故障时回滚的事务。 Azure 服务总线有自己的自己的事务,它不会与 Azure SQL 数据库事务共享它,因为 DTC 在 Azure 或任何云中都不可用。

你是做什么的?您将工作分解成孤立的部分,如果成功,则发出一条消息以表示继续(前进到下一个任务)或回滚(补偿操作)。

我的 cenário 在没有第二项的情况下工作得很好,因此在我尝试发布到同一事务中的主题和队列之后...... 任何人都通过它并且可以帮助我发布到事务范围内的队列和主题?

你提到的documentation,有一个代码sn-p就是这样做的:

var options = new ServiceBusClientOptions  EnableCrossEntityTransactions = true ;
await using var client = new ServiceBusClient(connectionString, options);

ServiceBusReceiver receiverA = client.CreateReceiver("queueA");
ServiceBusSender senderB = client.CreateSender("queueB");

ServiceBusReceivedMessage receivedMessage = await receiverA.ReceiveMessageAsync();

using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))

    await receiverA.CompleteMessageAsync(receivedMessage);
    await senderB.SendMessageAsync(new ServiceBusMessage());
    ts.Complete();

不幸的是,样本没有提到有一个主题是不够的。该主题下的订阅也是必要的。但这不是你遇到的问题。验证发送和发布在没有任何其他范围的情况下独立工作,因为服务总线在发现事务中登记的任何其他内容时不起作用。可能是错误消息具有误导性。

【讨论】:

以上是关于Azure 服务总线 - 发布到队列和事务范围内的主题的主要内容,如果未能解决你的问题,请参考以下文章

Azure Messaging-ServiceBus Messaging消息队列技术系列8-服务总线配额

Azure 服务总线队列性能

使用azure服务总线,如何将单个消息发布到多个队列?

从死信队列重新提交消息 - Azure 服务总线

Azure 服务总线触发队列在本地调试中未命中代码

从 Azure 函数将消息写入 Azure 服务总线队列