特定的 NServiceBus Sagas:对 Azure Table 存储中持久保存的 Saga 数据的并发访问
Particular NServiceBus Sagas: Concurrent Access to Saga Data Persisted in Azure Table Storage
当 saga 数据保存在 Azure Table 存储中时,这个问题是关于并发访问 saga 数据的。它还参考了 Particular 文档中的信息:http://docs.particular.net/nservicebus/nservicebus-sagas-and-concurrency
我们注意到,在并发执行处理程序的单个 saga 中,对 saga 数据的修改似乎在 "last one to post changes to azure table storage wins" 场景中运行。当将 NSB 与 Azure Table 存储结合使用作为 Saga 数据持久层时,这是预期的行为吗?
示例:
- Saga 数据中的整数 属性,假设它当前 = 5
- 在此 saga 中,5 个命令由同一处理程序的 5 个实例处理
- 每个命令处理程序递减传奇数据属性中的整数
- saga 数据中整数 属性 的最终值在处理这 5 条消息后实际上可能是 4 - 如果每条消息都由 saga 的新实例处理,可能在不同的服务器上,每个服务器都有一个副本表示整数 属性 为 5 的 saga 数据,将其递减为 4,然后 post 备份。我刚才描述的是高度并发的例子,但是如果同时处理 5 条消息中的任何一条,整数可能会大于 0,唯一一次 saga 数据整数 属性 达到 0 是当 5 条命令碰巧有串行执行。
此外,由于 Azure Table 存储支持开放式并发,是否可以为 Table 存储启用此功能,就像当 Raven 用作持久化技术?
如果这不可能,建议的处理方法是什么?目前我们正在订阅这样一种范例,即不允许 saga 中任何可能同时处理多条消息的处理程序修改 saga 数据,这意味着我们对 saga 消息的协调是通过 saga 外部的方式完成的,而不是使用 saga 数据正如我们最初预期的那样。
azure saga storage persister使用乐观并发,如果多个消息同时到达,最后更新的应该抛出异常,重新尝试使数据正确。
所以这听起来像是一个错误,你能分享一下你使用的是哪个版本吗?
PS:去年我们解决了一个听起来与此非常相似的问题 https://github.com/Particular/NServiceBus.Azure/issues/124 它已在 NServiceBus.Azure 5.2 及更高版本中得到解决
在使用特殊支持后 - 上述症状最终成为 NServiceBus.Azure 中的一个缺陷。此问题已由 Particular 在 NServiceBus.Azure 5.3.11 和 6.2+ 中修复。我可以亲自确认更新到 5.3.11 解决了我们的问题。
作为参考,此问题的一个明显标志是以下异常被抛出但未得到处理。
Failed to process message
Microsoft.WindowsAzure.Storage.StorageException: Unexpected response
code for operation : 0
异常详情会注明"UpdateConditionNotSatisfied" - 参考乐观并发检查
感谢来自 Particular 的 Yves Goeleven 和 Sean Feldman 诊断并解决了这个问题。
当 saga 数据保存在 Azure Table 存储中时,这个问题是关于并发访问 saga 数据的。它还参考了 Particular 文档中的信息:http://docs.particular.net/nservicebus/nservicebus-sagas-and-concurrency
我们注意到,在并发执行处理程序的单个 saga 中,对 saga 数据的修改似乎在 "last one to post changes to azure table storage wins" 场景中运行。当将 NSB 与 Azure Table 存储结合使用作为 Saga 数据持久层时,这是预期的行为吗?
示例:
- Saga 数据中的整数 属性,假设它当前 = 5
- 在此 saga 中,5 个命令由同一处理程序的 5 个实例处理
- 每个命令处理程序递减传奇数据属性中的整数
- saga 数据中整数 属性 的最终值在处理这 5 条消息后实际上可能是 4 - 如果每条消息都由 saga 的新实例处理,可能在不同的服务器上,每个服务器都有一个副本表示整数 属性 为 5 的 saga 数据,将其递减为 4,然后 post 备份。我刚才描述的是高度并发的例子,但是如果同时处理 5 条消息中的任何一条,整数可能会大于 0,唯一一次 saga 数据整数 属性 达到 0 是当 5 条命令碰巧有串行执行。
此外,由于 Azure Table 存储支持开放式并发,是否可以为 Table 存储启用此功能,就像当 Raven 用作持久化技术?
如果这不可能,建议的处理方法是什么?目前我们正在订阅这样一种范例,即不允许 saga 中任何可能同时处理多条消息的处理程序修改 saga 数据,这意味着我们对 saga 消息的协调是通过 saga 外部的方式完成的,而不是使用 saga 数据正如我们最初预期的那样。
azure saga storage persister使用乐观并发,如果多个消息同时到达,最后更新的应该抛出异常,重新尝试使数据正确。
所以这听起来像是一个错误,你能分享一下你使用的是哪个版本吗?
PS:去年我们解决了一个听起来与此非常相似的问题 https://github.com/Particular/NServiceBus.Azure/issues/124 它已在 NServiceBus.Azure 5.2 及更高版本中得到解决
在使用特殊支持后 - 上述症状最终成为 NServiceBus.Azure 中的一个缺陷。此问题已由 Particular 在 NServiceBus.Azure 5.3.11 和 6.2+ 中修复。我可以亲自确认更新到 5.3.11 解决了我们的问题。
作为参考,此问题的一个明显标志是以下异常被抛出但未得到处理。
Failed to process message Microsoft.WindowsAzure.Storage.StorageException: Unexpected response code for operation : 0
异常详情会注明"UpdateConditionNotSatisfied" - 参考乐观并发检查
感谢来自 Particular 的 Yves Goeleven 和 Sean Feldman 诊断并解决了这个问题。