问题
我正在尝试从表存储中删除很多可能存在或可能不存在的行。这笔交易是我需要最大限度地减少I / O并最大化带宽,所以1命中它们都会很棒。问题是如果任何批处理实体不存在,则整个批处理失败。
为什么
这也让我想到了一个设计问题 - 为什么请求只是返回一个删除结果,并指出哪些对象由于404而没有删除。为什么它会抛出异常?是什么原因。
更多信息
批量大小在表存储约束100中,它们都在同一分区内。
答案 0 :(得分:3)
要回答你的问题,我们无法避免这种情况。如果批处理中的实体失败,则整批将失败。
但是你可以做一件事:
当批处理失败时,它返回失败实体的索引。您可以做的是获取该批次并创建3个单独的批次。第一批将从第一个实体(第0个索引)到失败实体的索引(减1),第2个将是失败的实体(因此只是一个实体),最后一个将是从失败的实体索引到最后一个实体。对于失败的实体,您只需尝试DeleteIfExists
即可。因此,假设批次中有100个实体,并且假设第30个实体失败,那么您将创建3个批次:
批次1:第0到第29个实体(索引0 - 28)
批次2:第30个实体(单个实体)(索引29)
批次3:第31至第100个实体(索引30-99)
这也让我想到了一个设计问题 - 为什么不提出要求 只需返回一个删除结果,指示哪些对象是 由于404没有删除。为什么会抛出异常?是什么 原因。
我能想到的一个可能原因是因为Storage API遵守REST。您尝试删除资源,它不存在,因此API会抛出错误。此外,实体可能无法删除,不仅因为实体不存在,还因为请求中指定的if-match
条件头不匹配。详细说明,您可能只想在eTag
匹配时删除实体。在这种情况下,即使实体存在,您的删除操作也会失败。为了处理单个实体删除操作中的404错误,所有客户端SDK都实现了DeleteIfExists
类功能,这将导致404错误。
答案 1 :(得分:2)
在删除它们之前,您可以使用相同的PartitionKey和EntityKey PUT空实体。这样您就可以确定不会有404错误。这是对每个批次的两个一致调用,而不是多次重试并使应用程序的逻辑复杂化。不是一个理想的答案,但我们不是生活在一个理想的世界:)