";操作的意外响应代码:0”;执行Azure表存储批量删除时
本文关键字:Azure 存储 执行 删除 操作 quot 意外 响应 代码 | 更新日期: 2023-09-27 18:27:08
我使用的是.NET版本的Windows Azure存储库4.3.0。在我的ATS存储库类中,我有两种批量删除方法,如下所示:
public async Task DeleteAsync(IEnumerable<T> entities)
{
await ExecuteAsBatch(entities, (batch, entity) => batch.Delete(entity));
}
private async Task ExecuteAsBatch(IEnumerable<T> entities, Action<TableBatchOperation, T> batchAction)
{
var byPartition = entities.GroupBy(x => x.PartitionKey).ToList();
await byPartition.ForEachParallel(async group =>
{
// A maximum of 100 actions are allowed per batch job
var segments = group.ToList().ToSegmentedList(100);
await segments.ForEachParallel(async segment =>
{
var batch = new TableBatchOperation();
foreach (var entity in segment)
{
batchAction(batch, entity);
}
await Table.ExecuteBatchAsync(batch);
}, 10);
}, 10);
}
在我的代码中的其他地方,DeleteAsync()
方法工作正常。然而,在一个特定的地方,我在执行批处理时收到了以下错误消息:
Unexpected Response Code for Operation: 0
这是呼叫站点:
private async Task MergeAtsOrganizationUserEvents(int organizationId, IEnumerable<CustomerUserEvent> fromEvents, CustomerUser to)
{
var toDelete = (await fromEvents.SelectParallel(async fromEvent =>
{
var pkey = AtsOrganizationUserEventByMinute.GetPartitionKey(organizationId, fromEvent.OccurredOn);
var rkey = AtsOrganizationUserEventByMinute.GetRowKey(fromEvent.OccurredOn, fromEvent.CustomerUserEventId);
return await Ats.OrganizationUserEventByMinute.FindByPartitionRowAsync(pkey, rkey);
})).Where(x => x != null).ToList();
var toInsert = toDelete
.Select(x => AtsOrganizationUserEventByMinute.FromBase(x.OrganizationId, x.OccurredOn, x.CookieId,
to.CustomerUserId, x))
.ToList();
try
{
await Ats.OrganizationUserEventByMinute.UpsertAsync(toInsert);
await Ats.OrganizationUserEventByMinute.DeleteAsync(toDelete);
}
catch (Exception ex)
{
_logger.Error("Unable to merge {0} AtsOrganizationEvents for org {1}, to customer user {2}: {3}",
toInsert.Count, organizationId, to.CustomerUserId, ex.CompleteMessage());
throw;
}
}
上述UpsertAsync()
方法成功,但DeleteAsync()
失败。请注意,它无法删除与FindByPartitionRowAsync()
从表中检索到的实体完全相同的实体,所以我无法想象它与格式错误的实体或诸如此类的东西有什么关系。
下面是一个"toDelete"对象(JSON格式)的示例:
{
"CookieId":null,
"CustomerUserId":185766,
"CustomerUserEventId":3568687,
"OrganizationId":4190,
"EventName":"event1",
"SessionId":null,
"OccurredOn":"2014-10-20T18:17:09.9971379Z",
"UrlId":null,
"Url":null,
"ReferrerUrlId":null,
"ReferrerUrl":null,
"IsSynthetic":false,
"IpAddress":null,
"PartitionKey":"4190.2014.10.20",
"RowKey":"18.17.3568687",
"Timestamp":"2014-10-20T18:17:11.237+00:00",
"ETag":"W/''" datetime'2014-10-20T18%3A17%3A11.237Z'''""
}
Azure存储错误消息是出了名的毫无帮助,谷歌搜索也没有返回任何关于批删除失败的消息。
无论是在使用本地开发存储还是在生产中,这都会失败。
有什么想法吗?
"操作的意外响应代码:0"基本上意味着批处理中的第一个操作失败。失败操作的索引会在抛出的错误中返回,因此用户可以更容易地更改批处理中失败的特定操作。
您可以通过捕获StorageException并检查来获得有关失败请求和错误的更多信息
exception.RequestInformation.HttpStatusCode
exception.RequestInformation.ExtendedErrorInformation.ErrorCode
exception.RequestInformation.ExtendedErrorInformation.ErrorMessage
如果您使用OperationContext跟踪请求并使用适当的方法重载来接收OperationContext,那么在OperationContext的最后一个结果中也可以获得相同的信息。
我们将考虑在未来更改错误消息,以减少混淆。感谢您的反馈!
另一个原因是在键字段中使用了无效字符。如果你在谷歌上搜索这个错误消息,你可能会错过这个答案:
Azure表存储RowKey限制的字符模式?
关键字段中不允许使用的字符PartitionKey和RowKey属性的值中不允许使用以下字符:
正斜杠(/)字符
反斜杠()字符
数字符号(#)字符
问号字符
控制字符从U+0000到U+001F,包括:
水平制表符(''t)字符
换行符(''n)字符
回车(''r)字符
从U+007F到U+009F 的控制字符
在我的案例中,它已经解决了错误。"Microsoft.WindowsAzure.Storage.StorageException:"批中的元素0返回了意外的响应代码'
代码片段
table.CreateIfNotExists();
主代码
CloudStorageAccount SA=CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("SC"));
CloudTableClient tableClient=SA.CreateCloudTableClient();
CloudTable table=tableClient.GetTableReference("myWorld");
table.CreateIfNotExists();
TableBatchOperation batchOperation=new TableBatchOperation();
batchOperation.Insert(对象);
table.ExecuteBatch(batchOperation);