Azure表存储:并发更新覆盖以前的更改



我有一个程序可以更新Azure表存储表中的条目,如下所示:

  • 通过partitionKey和itemId从表筛选中恢复条目
  • 对已恢复对象的某些属性进行一些更改
  • 将更改保存回BD

因为我读到Azure存储表使用乐观并发性和Etag属性(例如,根据这个,或者这个关于Etag中存储的内容的stackoverflow问题(为了管理它,我想出了这个代码:

var query = table.CreateQuery<DynamicTableEntity>()
.Where(d => d.PartitionKey == customItem.PartitionKey
&& d.Properties[nameof(CustomItem.CustomItemId)].GuidValue == Guid.Parse(StringValueOfId)
)
.AsTableQuery();
var tr = table.ExecuteQuery<DynamicTableEntity>(query);
if (tr != null)
{
var entity = new DynamicTableEntity(customItem.PartitionKey, StringValueOfId);
entity.Properties.Add("MyDate", dateValue);
entity.Properties.Add("CustomProperty", new EntityProperty(JsonConvert.SerializeObject(customItem)));
entity.ETag = tr.FirstOrDefault().ETag;
TableOperation mergeOperation = TableOperation.Replace(entity);
try
{
TableResult result = await table.ExecuteAsync(mergeOperation);

}
catch (Exception ex)
{
throw new StorageException("Error saving data:" + ex.Message);
}
}

现在我仍然有并发问题。基本上是我的";CustomProperty"有某些字段为null的序列化属性。看起来A和B都试过了以设置"0"的值;CustomProperty"同时其中一个是重写另一个的变化。

然而,我预计由于";实体ETag";。我预计,如果A和B在BD的同时读取,然后A更新,由于实体的值不匹配,B的更新将失败。ETag。

有人能告诉我我做错了什么吗?我是否不明白如何正确避免这些一致性问题?

我发现了问题所在。这条线有错误的etag:

entity.ETag = tr.FirstOrDefault().ETag;

这是当我从DB中读取行以恢复要更新的项时的Etag,但实际上我需要当我读取customItem属性时的Etag值。

否则,这一行可能会覆盖在我恢复customItem,但在我执行查询var tr=table之前。ExecuteQuery(查询(

entity.Properties.Add("CustomProperty", new EntityProperty(JsonConvert.SerializeObject(customItem)));

换句话说,这解决了我的问题:

entity.ETag = customItem.ETag

最新更新