Transactions NServiceBus:Aren';MSMQ事务是否糟糕?

Transactions NServiceBus:Aren';MSMQ事务是否糟糕?,transactions,nservicebus,distributed-transactions,Transactions,Nservicebus,Distributed Transactions,我正在学习NServiceBus和MSMQ。我被告知MSMQ中的事务性队列很糟糕,使用它们对性能非常不利。有人知道为什么吗?我猜这是因为它使用了DTC,每个人都知道DTC并不是一个真正的可扩展解决方案。在我看来,MSMQ和NServiceBus并没有那么糟糕有几个原因,但我不知道我是否完全理解它是如何工作的。从逻辑上看,我可以想到3个地方,NServiceBus可能会使用事务来获得有保证的交付: 通过网络发送消息时,您可能希望使用事务来确保消息在丢弃之前已到达远程队列 从本地队列读取消息时,可能

我正在学习NServiceBus和MSMQ。我被告知MSMQ中的事务性队列很糟糕,使用它们对性能非常不利。有人知道为什么吗?我猜这是因为它使用了DTC,每个人都知道DTC并不是一个真正的可扩展解决方案。在我看来,MSMQ和NServiceBus并没有那么糟糕有几个原因,但我不知道我是否完全理解它是如何工作的。从逻辑上看,我可以想到3个地方,NServiceBus可能会使用事务来获得有保证的交付:

  • 通过网络发送消息时,您可能希望使用事务来确保消息在丢弃之前已到达远程队列
  • 从本地队列读取消息时,可能需要确保在丢弃消息之前已成功处理该消息
  • 向多个订阅者发布消息时,您可能希望确保消息在丢弃之前到达所有订阅者。(我真的希望这不是NServiceBus所做的)

  • 有人能告诉我NServiceBus是如何做到这一点的吗?

    第2点是正确的。您不希望消息导致错误,然后从裂缝中消失。您希望消息处理程序成功,在这种情况下,它将从队列中删除,或者失败并回滚,以便在达到可配置的重试次数后重试或发送到错误队列进行分析。

    Msmq事务不保证接收方已收到消息。该事务保证您的计算机上的msmq基础结构已接收到该消息,如果该消息是持久的(NSB中的默认值),则意味着该消息已在磁盘上持久化,并将在重新启动后继续存在。然后,msmq将在不阻塞呼叫者的情况下传递消息。这被称为“存储和转发”

  • 默认情况下,MSMQ仅保证本地MSMQ基础结构已收到消息。不要求接收服务器联机。但这可以启用(参见下面John的答案)

  • 这是NSB的关键卖点之一。使用跨本地队列和数据存储的事务(即分布式事务)的能力对于保证一致性至关重要。也就是说,如果某项操作失败,则不会在数据存储中保留任何内容,并且该消息会回滚并重试,而用户无需执行任何操作

  • 与#1相同。唯一的保证是每个订户最终都会收到发布的消息。只要您有可用的磁盘空间和发布服务器,就不会进行阻塞调用,因此调用将立即返回


  • 希望这有帮助

    第1点-不完整。如果您使用带有死信队列和TTRQ/TTBR计时器的负源日志和正源日志,事务性消息确实会提供此功能。然后,您可以准确地确定消息发生了什么情况—如果消息被拒绝、是否被传递、是否被处理。

    它们可能会有点性能问题—但我不会说它们是坏的—让操作具有事务性通常是一件“好事”(tm)。发送事务性MSMQ消息不使用DTC。不过,发送事务性MSMQ消息并将事实写入SQL server(例如)将使用DTC。