gal*_*bru 3 .net c# azure azure-service-fabric
我读过这篇关于使用可靠集合的文章,其中提到,一旦将对象提供给可靠集合,就不得修改对象,而更新可靠集合中的值的正确方法是获取副本(克隆)值,检查克隆值,然后更新 RC 中的克隆值。
\n\n使用不当:
\n\nusing (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}\nRun Code Online (Sandbox Code Playgroud)\n\n我的问题是:为什么我把对象交给 RC 后就不能修改它了?为什么我必须在更改对象之前克隆该对象?为什么我不能做类似的事情(在同一事务中更新对象):
\n\nusing (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}\nRun Code Online (Sandbox Code Playgroud)\n\n谢谢!
\n可靠字典是一个复制的对象存储。如果您在不通过 Reliable Dictionary 的情况下更新 Reliable Dictionary 内的对象(例如TryUpdateAsync),则可能会损坏状态。
例如,如果您使用引用更改 Reliable Dictionary 内的对象,则更改将不会复制到辅助副本。这是因为 Reliable Dictionary 不知道您更改了 TValue 之一。因此,如果副本发生故障转移,更改将会丢失。
上面是最简单的例子。直接修改对象可能会导致其他严重问题,例如以多种方式破坏 ACID。