修改 Service Fabric 可靠集合中的原始对象

gal*_*bru 3 .net c# azure azure-service-fabric

我读过这篇关于使用可靠集合的文章,其中提到,一旦将对象提供给可靠集合,就不得修改对象,而更新可靠集合中的值的正确方法是获取副本(克隆)值,检查克隆值,然后更新 RC 中的克隆值。

\n\n

使用不当:

\n\n
using (ITransaction tx = StateManager.CreateTransaction()) {\n   // Use the user\xe2\x80\x99s name to look up their data\n   ConditionalValue<User> user = \n      await m_dic.TryGetValueAsync(tx, name);\n\n   // The user exists in the dictionary, update one of their properties.\n   if (user.HasValue) {\n      // The line below updates the property\xe2\x80\x99s value in memory only; the\n      // new value is NOT serialized, logged, & sent to secondary replicas.\n      user.Value.LastLogin = DateTime.UtcNow; // Corruption!\n      await tx.CommitAsync(); \n   }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的问题是:为什么我把对象交给 RC 后就不能修改它了?为什么我必须在更改对象之前克隆该对象?为什么我不能做类似的事情(在同一事务中更新对象):

\n\n
using (ITransaction tx = StateManager.CreateTransaction()) {\n   // Use the user\xe2\x80\x99s name to look up their data\n   ConditionalValue<User> user = \n      await m_dic.TryGetValueAsync(tx, name);\n\n   // The user exists in the dictionary, update one of their properties.\n   if (user.HasValue) {\n      // The line below updates the property\xe2\x80\x99s value in memory only; the\n      // new value is NOT serialized, logged, & sent to secondary replicas.\n      user.Value.LastLogin = DateTime.UtcNow;\n\n      // Update\n      await m_dic.SetValue(tx, name, user.Value);\n\n      await tx.CommitAsync(); \n   }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

谢谢!

\n

Mer*_*SFT 5

可靠字典是一个复制的对象存储。如果您在不通过 Reliable Dictionary 的情况下更新 Reliable Dictionary 内的对象(例如TryUpdateAsync),则可能会损坏状态。

例如,如果您使用引用更改 Reliable Dictionary 内的对象,则更改将不会复制到辅助副本。这是因为 Reliable Dictionary 不知道您更改了 TValue 之一。因此,如果副本发生故障转移,更改将会丢失。

上面是最简单的例子。直接修改对象可能会导致其他严重问题,例如以多种方式破坏 ACID。