编辑: 我刚刚针对实际在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);
}
}
}));
}
- 我正在并行编写每个分区,以尝试提高插入性能。
- 在每个分区中,我依次写入所有记录;我用
.ExecuteBatchAsync()
一次写了100条记录。 - 运行此程序时,启用调试器,并设置一个断点。我还擦除了本地存储模拟器中的目标表。
- 没有其他东西可以和桌子说话了。
因此,我从一片空白开始,查看日志,一切都证实了我输入的记录是唯一的,但仍然出现“实体已存在”错误。 (这是因为[0]
是问题所在,因此它认为整个批次都已被写入。)
当我到达断点时,尽管最初是空白的DB,并且尝试写入该记录的日志记录只有一个,但在存储模拟器中(使用MS Azure Storage Explorer)查看记录仍然存在。
尽管成功完成了批处理,但似乎有时.ExecuteBatchAsync()
重试了很多?
这是怎么回事,如何防止它被错误抛出?
很高兴发布Debug输出的相关部分,但其中没有任何有趣的事情。