0

我遇到了一个问题。我必须在天蓝色表中存储一个列表。我正在做的是将它序列化为字符串并存储它。现在,当我阅读该行时,有些情况下我没有得到更新的列表。因此,如果我们将任何项目添加到列表中,那么旧的项目就会丢失。有没有人遇到过这个问题,解决方法是什么。

详细地说,假设我们有 3 个类,其中 C 扩展 B,B 扩展 A。现在 B 和 C 的任何对象也是 A 的对象。现在假设我们将 A 的所有对象(包括 B 和 c)维护为一个列表在 Azure 表的一列中。对象的当前状态为 [A',B',C',A''] 当我们有多个应用程序服务器时会发生问题。现在,Server1 想通过获取当前列表将 B 的实例添加到列表中,例如 [A',B',C',A''] 追加新实例让我们说 B'' 使其成为 [A',B',C' ,A'', B''] 同时 Server2 获取列表为 [A',B',C',A''] 并附加 C'' 以使 [[A',B',C',A ''],C'']。现在关于对象 B'' 的信息丢失了。如何缓解此类问题。

我正在使用 dot net 客户端库。下面是相同的代码

TableOperation retrieveTypedInstancesOperation = TableOperation.Retrieve<TypedInstancesRow>(partitionKey, RowKey);
TableResult retrievedTypedInstancesResult = instancesTable.Execute(retrieveTypedInstancesOperation);
List<string> instanceLists = new List<string>();

if (retrievedTypedInstancesResult.Result != null)
{
    string instances = ((TypedInstancesRow)retrievedTypedInstancesResult.Result).Instances;
    if (!String.IsNullOrEmpty(instances)) instanceLists = JsonConvert.DeserializeObject<List<string>>(instances);
}

instanceLists.Add(InstanceId);
hierarchy.PartitionKey = partitionKey;
hierarchy.RowKey =rowKey;
hierarchy.Instances = JsonConvert.SerializeObject(instanceLists);
TableOperation insertOperation = TableOperation.InsertOrReplace(hierarchy);
instancesTable.Execute(insertOperation);
4

1 回答 1

1

Azure 表存储使用 ETag 属性来管理此方案。

您尚未提供代码,因此我们不知道您使用的是什么客户端库。因此,您的问题的摘要答案是:

如果您使用Replace( Update) 操作,则需要在读取记录时获取 ETag 值。如果 ETag 值在原始读取和更新之间发生了变化,则更新将失败。请注意,如果提供通配符“*”值作为更新的 ETag 值,则可以覆盖此行为。

如果您使用InsertOrReplace操作,则无论原始读取和当前操作之间有任何更改,都会替换记录。我假设这是您正在使用的操作。

如果您修改代码以使用替换操作,则上述示例将变为:

服务器 1 和 2 读取表 [A',B',C',A''] 并且返回给两者的实体具有相同的 ETag 值。
服务器 1 发出包含原始 ETag 的 Replace 操作;这成功了,将字段修改为 [A',B',C',A'', B''] 并更改表中的 ETag 值。
服务器 2 发出替换操作,包括它读取的原始 ETag,这会失败,因为 ETag 值现在已过期。如何处理此失败取决于您的要求,但您可能需要通知您的客户端用户该操作由于其他用户所做的更改而失败;重新读取最新的记录状态([A',B',C',A'', B''] with new ETag);然后用户可以修改(到 [A',B',C',A'', B'', C''

于 2017-04-07T19:25:20.003 回答