繁体   English   中英

Azure存储表 - 插入批处理行并检查它们是否存在

[英]Azure Storage Table - Insert batch of row and check if they exists

我发送一些服务的查询并获得结果。 我想知道我过去是否已经得到了相同的“答案”。 所以,我计划使用Azure Table作为缓存机制。

我做了这个小POC:

TableBatchOperation batchOperation = new TableBatchOperation();
CachedUrl customer1 = new CachedUrl(Guid.Empty, "test1");
CachedUrl customer2 = new CachedUrl(Guid.Empty, "test2");
batchOperation.Insert(customer1);
batchOperation.Insert(customer2);
table.ExecuteBatch(batchOperation);

当我第一次运行此代码时,它运行正常。 在这结束时,我在表中有2行。

问题出在第二轮。 当我执行此代码时:

TableBatchOperation batchOperation = new TableBatchOperation();
CachedUrl customer1 = new CachedUrl(Guid.Empty, "test1");
CachedUrl customer2 = new CachedUrl(Guid.Empty, "test2");
CachedUrl customer3 = new CachedUrl(Guid.Empty, "test3");
batchOperation.Insert(customer1);
batchOperation.Insert(customer2);
batchOperation.Insert(customer3);
table.ExecuteBatch(batchOperation);

注意添加customer3

期望获得的是一条消息:

  • customer1 - 存在
  • customer2 - 存在
  • customer3 - 补充说

我实际得到的是这个异常(在ExecuteBatch()方法上):

请求信息请求ID:5116ee8a-0002-0024-7ac1-415787000000 RequestDate:星期五,18十一月2016 17:33:08 GMT StatusMessage:0:指定的实体已存在。 错误代码:EntityAlreadyExists

服务器发现#1实体存在,因此跳过整个任务。

我怎样才能得到预期的答案?

天真的解决方案是尝试逐个添加所有N个项目。 但是这个解决方案是最慢的(N HTTP请求而不是1个请求)。

Azure表存储批处理操作是原子操作,因此预计会在第一次失败的操作时返回。 批处理操作可能包含1000个操作,表服务在检测到第一个故障后继续执行所有操作没有多大意义。

存储异常返回批处理中失败操作的实际索引以及与之相关的错误。

在下面的示例中,失败操作的索引为0,错误为EntityAlreadyExists:

0 :指定的实体已存在。 错误代码:EntityAlreadyExists

您可以编写捕获StorageException的重试逻辑,解析错误,如果错误是EntityAlreadyExists,则从批处理中删除该索引的操作,然后重新提交批处理操作。

请参阅我在Nuget中实现的azure Storage Exception解析器,它为您提取StorageException对象中的失败操作索引和其他有用信息,如HttpStatusCode: https//www.nuget.org/packages/AzureStorageExceptionParser/

为了避免在每次失败的操作中多次来回调用azure,以下是您可以探索的替代解决方案:

每次向表中插入实体时,还会插入第二个实体,该实体具有仅包含行键的一个属性的相同分区键。 让我们调用第二个实体RowKeyTracker实体。 它将与原始实体具有相同的分区键,以便您可以执行批处理操作。 它将具有一个唯一的行键,您可以知道它以查询它,它将具有一个属性,该属性是该分区的附加行键。 如果RowKeyTracker实体已存在,则只需在每次插入新实体时将新行键附加到其分区键的行键属性,反之亦然,当您删除实体时,您也可以继续从RowKeyTracker中删除该行键实体。

因此,您可以使用此行键跟踪器实体通过先查询它来确定是否已插入该分区的Row键。

您可以将此方法与第一种方法(重试)结合使用,以获得更强大的解决方案

这是预期的行为。 只要该批次中的任何实体失败,整个批次就会失败。

你可以做的一件事是使用InsertOrReplace方法而不是Insert 这将更新实体(如果存在),否则插入实体。

文档

将TableOperation添加到TableBatchOperation,如果实体不存在,则将指定的实体插入表中; 如果实体确实存在,那么其内容将被提供的实体替换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM