我们的应用程序执行了几批TableBatchOperation
. 我们确保这些表批处理操作中的每一个都有
- 100 个或更少的表操作
- 仅针对一个实体分区键的表操作
沿着以下思路:
foreach (var batch in batches)
{
var operation = new TableBatchOperation();
operation.AddRange(batch.Select(x => TableOperation.InsertOrReplace(x)));
await table.ExecuteBatchAsync(operation);
}
- 当我们使用模拟存储时,我们遇到了
Microsoft.WindowsAzure.Storage.StorageException
“批处理中的元素 99 返回了意外的响应代码”。 - 当我们使用生产 Azure 时,一切正常。
模拟存储配置如下:
<add key="StorageConnectionString" value="UseDevelopmentStorage=true;" />
我担心,尽管在生产环境(我们使用真正的 Azure)中一切正常,但它与模拟存储一起爆炸的事实可能表明我们做了一些我们不应该做的事情。
我已经用调试器运行了它(在它爆炸之前)并验证了它(根据 API):
- 整个操作序列化为 JSON 时只有 492093 个字符(UTF-16 为 984186 个字节)
- 正好有 100 次操作
- 所有实体都具有相同的分区键
编辑: 看起来其中一项(#71/100)导致此失败。在结构上它与其他项目没有什么不同,但是它确实有一些相当长的字符串属性 - 所以也许有一个未记录的限制/错误?
编辑: 以下 Unicode UTF-16 字节序列(在字符串属性上)足以导致异常:
r e n U+0019 space
114 0 101 0 110 0 25 0 115 0 32 0
(这是导致异常的字节25 0 115 0即 unicode end-of-medium U+0019)。
编辑: 失败实体的完整示例:
JSON:
{"SomeProperty":"ren\u0019s ","PartitionKey":"SomePartitionKey","RowKey":"SomeRowKey","Timestamp":"0001-01-01T00:00:00+00:00","ETag":null}
实体类:
public class TestEntity : TableEntity
{
public string SomeProperty { get; set; }
}
实体对象构造:
var entity = new TestEntity
{
SomeProperty = Encoding.Unicode.GetString(new byte[]
{114, 0, 101, 0, 110, 0, 25, 0, 115, 0, 32, 0}),
PartitionKey = "SomePartitionKey",
RowKey = "SomeRowKey"
};