特定的NServiceBus传奇:对Azure表存储中持久化的传奇数据的并发访问



这个问题是关于在Azure表存储中持久化传奇数据时对传奇数据的并发访问。它还参考了特殊情况文件中的信息:http://docs.particular.net/nservicebus/nservicebus-sagas-and-concurrency

我们注意到,在同时执行处理程序的单个传奇中,对传奇数据的修改似乎是在"最后一个发布对azure表存储的更改的人获胜"的场景中操作的。当将NSB与Azure表存储一起用作Saga数据持久层时,这是预期行为吗?

示例:

  1. Saga Data中的Integer属性,假设它当前=5
  2. 在这个传奇中,5个命令由同一处理程序的5个实例处理
  3. 每个命令处理程序递减传奇数据中的integer属性
  4. 在处理这5条消息后,传奇数据中整数属性的最终值实际上可能是4——如果每条消息都由传奇的一个新实例处理,可能在不同的服务器上,每个服务器都有一份传奇数据副本,指示整数属性是5,将其递减到4,然后进行备份。我刚才描述的是一个非常并发的例子,然而,如果同时处理5条消息中的任何一条,则整数可能会大于0,saga数据整数属性唯一达到0的时间是当5条命令碰巧串行执行时

此外,由于Azure表存储支持乐观并发,是否可以像Raven用作持久性技术时为RavenDB启用此功能一样,为表存储启用此功能?

如果无法做到这一点,建议采用什么方法来处理?目前,我们订阅了一种范式,即传奇中任何可能同时处理多条消息的处理程序都不允许修改传奇数据,这意味着我们对传奇消息的协调是通过传奇外部的方式完成的,而不是像我们最初打算的那样使用传奇数据。

在与Special support合作后,上述症状最终成为NServiceBus.Azure中的一个缺陷。此问题已由Special在NServiceBus.Azure 5.3.11和6.2+中进行了修补。我可以亲自确认,更新到5.3.11解决了我们的问题。

作为参考,这个问题的一个明显迹象是以下异常被抛出而没有得到处理。

无法处理消息Microsoft.WindowsAzure.Storage.StorageException:意外响应操作代码:0

异常的详细信息将指示"UpdateConditionNotSatisfied"-指乐观并发检查。

感谢Special的Yves Goeleven和Sean Feldman诊断并解决了这个问题。

azure saga存储持久器使用乐观并发,如果多条消息同时到达,最后一条更新的消息应该抛出异常,重试并使数据再次正确。

所以这听起来像一个bug,你能分享你使用的版本吗

附言:去年我们解决了一个听起来与此非常相似的问题https://github.com/Particular/NServiceBus.Azure/issues/124它已在NServiceBus.AAzure 5.2及更高版本的中得到解决

最新更新