0

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

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

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

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

4

2 回答 2

0

@菲尔,

首先,您不应该将 MSDTC 与 SQL Azure 一起使用——它不受支持。建议使用该功能,但仅在审查中。Azure 不支持 DTC。或者,您可以查看以下建议以使用 SqlTransaction 方法。

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

于 2014-10-08T02:32:30.147 回答
0

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

我们将发送和发布明确地推送到接收事务范围之外,以防止升级到 DTC,以便事务是 sql 本地的,所以我怀疑这就是这里发生的事情。

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

会是这样吗?它在第二次打开时抛出?

于 2014-10-08T08:10:41.073 回答