执行更新元素时是不是需要考虑 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<T>(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<T>(partitionKey, rowKey))
那样再次获取它
如果变量element
是从客户端构造的,那么从服务器端检索ETag
并将其设置为element
没有多大意义。
要明确禁用并发检查,您应该在执行替换操作之前将 ETag 属性设置为通配符 (*
)。即
customer.ETag = "*";
进一步阅读
Managing Concurrency in Microsoft Azure Storage Dealing with TableStorage ETag with SDK >= 2.1【讨论】:
以上是关于执行更新元素时是不是需要考虑 Azure 表存储中的 Etag?的主要内容,如果未能解决你的问题,请参考以下文章
如何为某些应用程序配置 MFA(在 Azure B2C 中)每天强制执行一次(而不是每次登录时)?
Azure Function Nodejs 中是不是可以休眠?