【发布时间】:2020-07-02 08:33:36
【问题描述】:
编辑: 我刚刚在真正的 Azure 上再次测试了这个临时创建的表,并且效果很好,而我可以通过本地模拟器反复实现这一点。所以我怀疑这是模拟器的错误?
有人知道吗?
与Getting "Entity already exists" error writing aggregates to Azure Table Storage (with Azure Function) 非常相似,除了我已注销所有记录并且我非常确信我的代码正在生成唯一的分区/行键,而 不 中已经存在存储表。
我的插入代码如下所示:
public static async Task BatchInsert<TEntity>(this CloudTable table, IEnumerable<TEntity> entities)
where TEntity : TableEntity
{
var entityPartitionGroups = entities.GroupBy(e => e.PartitionKey).ToList();
await Task.WhenAll(entityPartitionGroups.Select(async partitionGroup =>
{
var batches = partitionGroup.Batch(BatchSize).Select(batch => batch.ToList()).ToList();
foreach (var batchToInsert in batches)
{
var batchOperation = new TableBatchOperation();
foreach (var tableEntity in batchToInsert)
{
batchOperation.Insert(tableEntity);
}
try
{
var entitiesAsStrings = batchToInsert.Select((entity, i) => $"{i}: {entity.PartitionKey}, {entity.RowKey}").StringJoin(";");
Debug.WriteLine("Writing: " + entitiesAsStrings);
await table.ExecuteBatchAsync(batchOperation);
Debug.WriteLine("Wrote: "+entitiesAsStrings);
}
catch (StorageException ex)
{
// break point here.
throw new AzureTableBatchInsertException(batchToInsert, ex);
}
}
}));
}
- 我正在并行编写每个分区,以尝试提高插入性能。
- 在每个Partition内,我把所有的记录串联起来;我使用
.ExecuteBatchAsync()一次写入 100 条记录。 - 当我运行它时,启用调试器并设置断点。我还擦除了本地存储模拟器中的目标表。
- 没有其他可以与表对话的东西正在运行。
所以我从一张白纸开始,查看日志,一切都确认我输入的记录是唯一的,但我仍然收到“实体已经存在”错误。 (它指责元素[0] 是问题所在,所以它认为整批都已经写好了。)
当我到达断点并在存储模拟器中查看(使用 MS Azure 存储资源管理器)时,记录仍然存在,尽管最初是空白数据库,并且只有 1 条尝试写入记录的日志记录。
看起来很像有时.ExecuteBatchAsync()重试一个批次,尽管已经成功编写了它?
这是怎么回事,我该如何阻止它错误地投掷?
很高兴发布调试输出的相关部分,但其中没有任何有趣的内容。
【问题讨论】:
-
我刚刚再次测试了这个,指向一个在真实 Azure 上临时创建的表,效果很好,而我可以通过本地模拟器反复实现这一点。所以我怀疑这是模拟器的错误?
标签: azure azure-table-storage azure-storage-emulator