从 Azure Table 存储中删除批次时如何避免 404

How to avoid a 404 when deleting batches from Azure Table Storage

问题

我正在尝试从 table 存储中删除很多行,这些行可能存在也可能不存在。交易是我需要最小化 I/O 并最大化带宽,因此 1 次命中来统治它们将是非常棒的。问题是,如果任何批次实体不存在,则整个批次都会失败。

为什么

这也让我想到了一个设计问题 - 为什么请求不只是 return 一个删除结果,指示哪些对象由于 404 而未被删除。为什么会抛出异常?这是什么原因。

更多信息

批处理大小在 Table 存储限制 100 内,并且它们都在同一分区内。

回答你的问题,这种情况是无法避免的。如果批次中的一个实体失败,则整个批次都将失败。

但是您可以做一件事:

当批处理失败时,它returns失败实体的索引。您可以做的是获取该批次并从中创建 3 个单独的批次。第一批将从第一个实体(第 0 个索引)到失败实体的索引(减去一个),第二批将是失败的实体(因此只有一个实体),最后一个将从失败的实体索引到最后一个实体.对于失败的实体,您可以简单地尝试 DeleteIfExists。因此,假设您在一个批次中有 100 个实体,假设第 30 个实体失败,您将创建 3 个批次:

第 1 批次:第 0 到第 29 个实体(索引 0 - 28)

第 2 批:第 30 个实体(单个实体)(索引 29)

第 3 批:第 31 到第 100 个实体(索引 30 - 99)

This also brings me to a design question - why doesn't the request simply return a deletion result with indication of which objects were not deleted due to 404. Why does it throw an exception? What is the reason for it.

我能想到的一个可能原因是存储 API 坚持 REST。您尝试删除资源,但它不存在,因此 API 会抛出错误。此外,实体可能无法删除,不仅因为该实体不存在,而且因为请求中指定的 if-match 条件 header 不匹配。详细来说,您可能希望仅在 eTag 匹配时删除实体。在这种情况下,即使实体存在,您的删除操作也会失败。为了处理单个实体删除操作的 404 错误,所有客户端 SDK 都实现了 DeleteIfExists 种会处理 404 错误的功能。

您可以 PUT 具有相同 PartitionKey 和 EntityKey 的空实体,然后再删除它们。这样您就可以确保不会出现 404 错误。这是对每个批次的两次一致调用,而不是多次重试并使应用程序的逻辑复杂化。这不是一个理想的答案,但我们并不生活在一个理想的世界中:)