【问题标题】:Transactions in NServicebus using Azure Service Bus Transport使用 Azure 服务总线传输的 NServicebus 中的事务
【发布时间】:2014-09-22 14:59:38
【问题描述】:

我在特定端点中有几个消息处理程序,它们针对 SQL Azure 数据库执行工作(目前仍在使用本地 SQL 2012 实例)。我有一个发布 2 个事件的命令处理程序,分别称为 X 和 Y。在同一个端点中,我有一个 X 订阅者和一个 Y 订阅者。这两个订阅者在内部使用相同的数据访问组件,称为 Z。注入是按调用配置的,而不是共享的。

组件 Z 在幕后使用 Entity Framework 6。我遇到的问题是,仅打开数据库就会引发 SqlException 并抱怨 MSDTC 升级。

我已将处理程序暂时包装在 TransactionScope.Suppress 中,这已经停止了错误,但我相信我遗漏了一些更基本的东西。

将端点配置为非事务性是否很简单?我原以为这会起作用,因为我已配置为使用 Azure 服务总线作为传输机制。如果我这样做,如果在消息处理程序中引发异常,NServiceBus 仍会重试吗? (直到 SLR 限制——不是问题的一部分,我也理解幂等性问题)。

【问题讨论】:

  • 您是使用 SQL Server 作为 NServiceBus 的传输还是仅仅作为数据存储?至于 Azure 服务总线传输 - NSB 将像往常一样使用 FLR(和 SLR,如果已配置)重试异常。
  • 它看起来像一个配置问题,但我很难理解你的设置(你使用什么 NServiceBus 传输?)
  • SQL Server 仅用于数据存储。我使用 Azure 服务总线作为传输。我还读到如果我将其设为非事务性,我将不会获得 FLR 或 SLR 重试?对吗?

标签: azure transactions nservicebus nservicebus4


【解决方案1】:

@菲尔,

首先,您不应该将 MSDTC 与 SQL Azure 一起使用 - 它不受支持。建议使用该功能,但仅限under review。 Azure 不支持 DTC。或者,您可以查看 following suggestion 以使用 SqlTransaction 方法。

其次,您使用的传输与您的数据访问无关。由于您使用的是 Azure 服务总线,因此它不会成为您的处理程序代码的一部分。使处理程序成为事务是强制进行原子更改或回滚。无论您的处理程序如何,都会重试。挑战在于,当处理程序/端点不是事务性的,并且在处理程序内第一次写入数据库成功而第二次失败时,第一次写入将不会被恢复。至于 Azure 服务总线作为一种传输方式,它本质上不是事务性的(即没有 DTC)。

【讨论】:

  • 我并没有尝试以任何方式使用 MSDTC,我只是对它被调用感到惊讶,因此我提出了问题。从那以后,我了解了重试在服务总线下的工作方式,因此希望路径更清晰。
【解决方案2】:

您使用的是哪个版本的 NServiceBus.Azure?你有异常的堆栈跟踪吗?它来自哪里?

我们将发送和发布显式地推送到接收事务范围之外,以防止升级到 DTC,因此事务对于 sql 来说是本地的,所以我怀疑这就是这里发生的事情。

根据您的描述,您似乎为每个处理程序(每个调用容器配置)使用不同的数据访问实例,并且您在同一条消息上有多个处理程序。如果这两个都打开到 SQL 的新连接,您也会看到升级(即使它是同一台服务器)

可以吗?它在第二次打开时抛出?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-25
    • 2016-12-31
    • 2014-06-07
    • 2021-06-06
    相关资源
    最近更新 更多