执行更新元素时​​是不是需要考虑 Azure 表存储中的 Etag?

Posted

技术标签:

【中文标题】执行更新元素时​​是不是需要考虑 Azure 表存储中的 Etag?【英文标题】:Do I need to consider Etag in Azure Table Storage when performing Update element?执行更新元素时​​是否需要考虑 Azure 表存储中的 Etag? 【发布时间】:2019-04-22 08:18:40 【问题描述】:

我不知道是否需要考虑使用 ETag 来防止多个线程同时操作单个实体。 以下是我目前的实现:

public void UpdateElement(T element)

    Exceptions.ThrowIfNull(element, "record");
    var partitionKey = element.PartitionKey;
    var rowKey = element.RowKey;
    var result = Table.Execute(TableOperation.Retrieve<T>(partitionKey, rowKey));
    if (result?.Result != null)
    
        Table.Execute(TableOperation.Replace(element));
    

所以我在这里想要实现的是,线程 A 和线程 B 同时操作同一个实体,线程 A 首先更新了这个实体。当线程 B 试图更新它时,我们应该给线程 B 一个错误,说“你不能执行更新操作”。

【问题讨论】:

变量element从何而来?如果它来自服务器查询,那么它已经包含 ETag,您不需要像var result = Table.Execute(TableOperation.Retrieve&lt;T&gt;(partitionKey, rowKey)) 那样再次检索实体。此外,如果element 是从客户端构造的并且不是来自服务器查询,那么您上面的代码并没有真正按照您的期望检查 ETag,因为element 不包含任何 ETag。 感谢您的回答!但我想知道我们应该为设置 Etag 提供哪个值。例如,我有两个线程,线程 A 和线程 B,它们都想更新现有元素 ELEMENT。在这种情况下,我们应该如何为 A&B 的操作设置 Etag?谢谢! 【参考方案1】:

ETag 不是为手动设置而设计的。相反,它专为 Read-Edit-Write 场景而设计,并防止由于并发操作而导致 Dirty Write

如果变量element是从服务器查询中获取的,它已经包含了来自服务器端的ETag,你不需要像var result = Table.Execute(TableOperation.Retrieve&lt;T&gt;(partitionKey, rowKey))那样再次获取它

如果变量element是从客户端构造的,那么从服务器端检索ETag并将其设置为element没有多大意义。

明确禁用并发检查,您应该在执行替换操作之前将 ETag 属性设置为通配符 (*)。即

customer.ETag = "*";

进一步阅读

Managing Concurrency in Microsoft Azure Storage Dealing with TableStorage ETag with SDK >= 2.1

【讨论】:

以上是关于执行更新元素时​​是不是需要考虑 Azure 表存储中的 Etag?的主要内容,如果未能解决你的问题,请参考以下文章

oracle数据库哪个表存着host与port

如何为某些应用程序配置 MFA(在 Azure B2C 中)每天强制执行一次(而不是每次登录时)?

Azure Function Nodejs 中是不是可以休眠?

azure 是不是有可能制定强制执行定价层的政策?

(AZURE cosmosDB/mongoDB) 更新数组中对象的特定元素的字段

我们是不是能够使用 Snappy-data 更新 Azure 数据湖中的记录?还是仅附加 Azure 数据湖?