【问题标题】:Azure Table Storage batch insert with potentially pre-existing rowkeysAzure 表存储批量插入可能预先存在的行键
【发布时间】:2013-05-28 22:29:44
【问题描述】:

我正在尝试将一组简单的插入操作发送到 Azure 表存储,但似乎整个批处理事务已失效,并且使用托管的 azure 存储客户端,如果有单个 ExecuteBatch 方法本身会引发异常将批次插入到预先存在的记录中。 (使用 2.0 客户端):

public class SampleEntity : TableEntity
{
    public SampleEntity(string partKey, string rowKey)
    {
        this.PartitionKey = partKey;
        this.RowKey = rowKey;
    }
}


var acct = CloudStorageAccount.DevelopmentStorageAccount;
var client = acct.CreateCloudTableClient();
var table = client.GetTableReference("SampleEntities");

var foo = new SampleEntity("partition1", "preexistingKey");
var bar = new SampleEntity("partition1", "newKey");

var batchOp = new TableBatchOperation();
batchOp.Add(TableOperation.Insert(foo));
batchOp.Add(TableOperation.Insert(bar));

var result = table.ExecuteBatch(batchOp);  // throws exception: "0:The specified entity already exists."

使用 InsertOrMerge 可以避免批处理级异常,但随后每个单独的操作响应都会返回 204,无论该特定操作是否插入或合并它。因此,客户端应用程序似乎不可能保留它或集群中的另一个节点是否插入了记录的知识。不幸的是,在我目前的情况下,这些知识对于一些下游同步是必要的。

是否有一些配置或技术允许批量插入继续进行并返回每个项目的特定响应代码,而不会引发一揽子异常?

【问题讨论】:

    标签: azure azure-table-storage


    【解决方案1】:

    如您所知,由于批处理是一种事务操作,因此您将获得一种全有或全无的交易。批处理事务有趣的一件事是您获得批处理中第一个失败实体的索引。因此,假设您尝试在批处理中插入 100 个实体,并且表中已经存在第 50 个实体,批处理操作将为您提供失败实体的索引(在本例中为 49)。

    是否有一些配置或技术允许批量插入 继续并返回每个项目的特定响应代码,而不 抛出一个全面的异常?

    我不这么认为。一旦第一个实体失败,交易就会失败。它甚至不会尝试处理其他实体。

    可能的解决方案(只是大声思考:))

    如果我理解正确,您的关键要求是确定是否插入或合并(或替换)实体。为此,方法是从批次中分离出失败的实体并分别处理它们。基于此,我可以想到两种方法:

    1. 在这种情况下,您可以做的就是将该批次分成 3 批次:第一批将包含 49 个实体,第二批将包含 只有 1 个实体(失败),第三批将包含 50 个 实体。您现在可以在第一批中插入所有实体,决定 你想对那个失败的实体做什么并尝试插入 第三批。你需要一遍又一遍地重复这个过程 直到此操作完成。
    2. 另一个想法是从批次中删除失败的实体并 重试该批次。所以在上面的例子中,在你的第一次尝试中 您将尝试 100 个实体,在第二次尝试中,您将尝试 99 个 实体等跟踪失败的实体全部 期间(以及他们失败的原因)。一旦批次 操作成功完成,您可以使用所有 失败的实体。

    【讨论】:

      猜你喜欢
      • 2019-03-16
      • 2021-11-26
      • 2021-01-09
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 2014-11-08
      • 1970-01-01
      • 2021-03-06
      相关资源
      最近更新 更多