Azure表存储批插入,可能包含预先存在的行键

Azure表存储批插入,可能包含预先存在的行键,azure,azure-table-storage,Azure,Azure Table Storage,我试图向Azure表存储发送一个简单的插入操作批,但整个批处理事务似乎无效,并且,如果批处理中有一个插入到预先存在的记录,则ExecuteBatch方法本身会使用托管Azure存储客户机引发异常。(使用2.0客户端): 使用InsertOrMerge可以避免批处理级别的异常,但是每个单独的操作响应都会返回一个204,不管该特定操作是否插入或合并了它。因此,客户机应用程序似乎不可能保留它或集群中的另一个节点是否插入了记录的信息。不幸的是,在我目前的情况下,这种知识对于一些下游同步是必要的 是否有一

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

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


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

正如您已经知道的,由于批量是一种事务操作,因此您得到的是一种“全部”或“无”类型的交易。批处理事务的一个有趣之处是,您可以获得批处理中第一个失败实体的索引。因此,假设您试图在一个批中插入100个实体,并且表中已经存在第50个实体,那么批处理操作将为您提供失败实体的索引(在本例中为49)

是否存在允许批量插入的配置或技术 继续并返回每个项目的特定响应代码 抛出一揽子例外

我不这么认为。当第一个实体失败时,事务将立即失败。它甚至不会尝试处理其他实体

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

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

  • 在这种情况下,您可能会将该批次分成3个 批次:第一批将包含49个实体,第二批将包含 只有1个实体(失败),第三批将包含50个实体 实体。现在,您可以在第一批中插入所有实体,请决定 您希望如何处理失败的实体并尝试插入 第三批。你需要一次又一次地重复这个过程 直到该操作完成
  • 另一个想法是从批处理中删除失败的实体,然后 重试该批处理。在上面的例子中,在你的第一次尝试中 您将尝试使用100个实体,第二次尝试使用99个实体 实体等等,等等,跟踪所有失败的实体 同时(说明他们失败的原因)。一批 操作成功完成后,您可以使用所有 失败的实体
  • 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."