Azure Table 保持一致性
Azure Table Maintaining consistency
我遇到了一个问题。我必须在 azure table 中存储一个列表。我正在做的是将它序列化为一个字符串并存储它。现在,当我阅读该行时,有些情况下我没有获得更新的列表。结果 post 如果我们向列表中添加任何项目,则阅读会丢失较旧的项目。有没有人遇到过这个问题,解决方法是什么。
为了详细说明,假设我们有 3 个 类,其中 C 扩展 B,B 扩展 A。
现在 B 和 C 的任何对象也是 A 的对象。
现在假设我们将 A 的所有对象(包括 B 和 c)维护为 Azure Table 的一列中的列表。对象的当前状态 [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'' 的信息丢失了。
如何缓解此类问题。
我使用的是.net 客户端库。
下面是 same
的代码
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);
Azure Table 存储使用 ETag 属性 来管理这种情况。
您还没有提供代码,所以我们不知道您使用的是什么客户端库。因此,对您的问题的总结回答是:
如果您使用 Replace
(Update
) 操作,这需要一个在读取记录时获得的 ETag 值。如果 ETag 值在原始读取和更新之间发生变化,则更新将失败。请注意,如果提供通配符“*”值作为更新的 ETag 值,则可以覆盖此行为。
如果您使用 InsertOrReplace
操作,则无论原始读取和当前操作之间有任何更改,记录都将被替换。我假设这是您正在使用的操作。
如果您修改代码以使用替换操作,您的上述示例将变为:
服务器 1 和 2 读取 table [A',B',C',A''] 并且返回给两者的实体具有相同的 ETag 值。
Server 1发出包含原始ETag的Replace操作;这是成功的并将字段修改为 [A',B',C',A'', B''] 并更改 table.
中的 ETag 值
服务器 2 发出替换操作,包括它读取的原始 ETag,但由于 ETag 值现在已过时而失败。
如何处理此故障取决于您的要求,但您可能随后需要通知您的客户端用户由于其他用户所做的更改导致操作失败;使用新的 ETag 重新读取最新的记录状态([A',B',C',A'', B'']);然后用户可以修改([A',B',C',A'', B'', C''],我认为这是您的要求)。
我遇到了一个问题。我必须在 azure table 中存储一个列表。我正在做的是将它序列化为一个字符串并存储它。现在,当我阅读该行时,有些情况下我没有获得更新的列表。结果 post 如果我们向列表中添加任何项目,则阅读会丢失较旧的项目。有没有人遇到过这个问题,解决方法是什么。
为了详细说明,假设我们有 3 个 类,其中 C 扩展 B,B 扩展 A。 现在 B 和 C 的任何对象也是 A 的对象。 现在假设我们将 A 的所有对象(包括 B 和 c)维护为 Azure Table 的一列中的列表。对象的当前状态 [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'' 的信息丢失了。 如何缓解此类问题。
我使用的是.net 客户端库。 下面是 same
的代码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);
Azure Table 存储使用 ETag 属性 来管理这种情况。
您还没有提供代码,所以我们不知道您使用的是什么客户端库。因此,对您的问题的总结回答是:
如果您使用 Replace
(Update
) 操作,这需要一个在读取记录时获得的 ETag 值。如果 ETag 值在原始读取和更新之间发生变化,则更新将失败。请注意,如果提供通配符“*”值作为更新的 ETag 值,则可以覆盖此行为。
如果您使用 InsertOrReplace
操作,则无论原始读取和当前操作之间有任何更改,记录都将被替换。我假设这是您正在使用的操作。
如果您修改代码以使用替换操作,您的上述示例将变为:
服务器 1 和 2 读取 table [A',B',C',A''] 并且返回给两者的实体具有相同的 ETag 值。
Server 1发出包含原始ETag的Replace操作;这是成功的并将字段修改为 [A',B',C',A'', B''] 并更改 table.
中的 ETag 值
服务器 2 发出替换操作,包括它读取的原始 ETag,但由于 ETag 值现在已过时而失败。
如何处理此故障取决于您的要求,但您可能随后需要通知您的客户端用户由于其他用户所做的更改导致操作失败;使用新的 ETag 重新读取最新的记录状态([A',B',C',A'', B'']);然后用户可以修改([A',B',C',A'', B'', C''],我认为这是您的要求)。