首页 文章

Azure表存储批处理插入,可能存在预先存在的rowkeys

提问于
浏览
2

我正在尝试向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,无论该特定操作是否插入或合并它 . 因此,客户端应用程序似乎无法保留其是否或集群中的其他节点插入记录的知识 . 不幸的是,在我目前的情况下,这种知识对于某些下游同步是必要的 .

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

1 回答

  • 1

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

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

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

    Possible Solutions (Just thinking out loud :))

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

    • 在这种情况下您可以做的是将批次拆分为3批次:第一批次将包含49个实体,第二批次仅包含1个实体(失败),第3批次将包含50个实体 . 您现在可以在第一批中插入所有实体,确定要对该失败实体执行的操作,并尝试插入第三批 . 您需要反复重复此过程,直到此操作完成为止 .

    • 另一个想法是从批处理中删除失败的实体并重试该批处理 . 因此,在上面的示例中,在您的第一次尝试中,您将尝试使用99个实体,依此类推,以便始终跟踪失败的实体(原因是它们失败的原因) . 批处理操作成功完成后,您可以使用所有失败的实体 .

相关问题