简体   繁体   English

执行Azure Table Storage批删除时,“操作的意外响应代码:0”

[英]“Unexpected Response Code for Operation: 0” when executing Azure Table Storage batch delete

I'm using version 4.3.0 of the Windows Azure Storage libraries for .NET. 我使用的是适用于.NET的Windows Azure存储库的版本4.3.0。 In my ATS repository class, I have a couple of batch delete methods that look like this: 在我的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);
}

In other places in my code, that DeleteAsync() method works correctly. 在我代码的其他地方,该DeleteAsync()方法可以正常工作。 However, in one particular place, I get this error message when executing the batch: 但是,在一个特定的位置,执行批处理时出现此错误消息:

Unexpected Response Code for Operation: 0

Here's the call site: 这里是呼叫站点:

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;
    }
}

The UpsertAsync() method above succeeds, but the DeleteAsync() fails. 上面的UpsertAsync()方法成功,但是DeleteAsync()失败。 Note that it fails to delete precisely the same entities that FindByPartitionRowAsync() retrieved from the table, so I can't quite imagine how it could have anything to do with malformed entities or anything of that ilk. 请注意,它无法删除与从表中检索到的FindByPartitionRowAsync()完全相同的实体,因此我无法想象它与变形的实体或任何类似的实体有什么关系。

Here's an example of one of the "toDelete" objects (in JSON format): 这是一个“ 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 Storage error messages are notoriously and spectacularly unhelpful, and Googling has returned nothing about batch deletes failing with this particular error. 众所周知,Azure存储错误消息无济于事,并且无济于事,并且Googling对于因该特定错误而导致的批量删除失败没有返回任何信息。

This fails both when using local development storage and in production. 在使用本地开发存储和在生产中这都失败。

Any thoughts? 有什么想法吗?

'Unexpected Response Code for Operation: 0' basically means that the first operation in the batch failed. “意外的操作响应代码:0”基本上意味着该批次中的第一个操作失败。 The index of the failed operation is returned in the error thrown so it makes it easier for users to go and change the specific operation in the batch that failed. 失败的操作的索引会在抛出的错误中返回,因此它使用户可以更轻松地更改失败的批处理中的特定操作。

You can get more information about the request that failed and the error by catching the StorageException and checking: 您可以通过捕获StorageException并检查以下内容来获取有关失败的请求和错误的更多信息:

  • exception.RequestInformation.HttpStatusCode
  • exception.RequestInformation.ExtendedErrorInformation.ErrorCode
  • exception.RequestInformation.ExtendedErrorInformation.ErrorMessage

The same information is also available in the OperationContext's last result if you use an OperationContext to track the request and use suitable method overloads that take in the OperationContext. 如果您使用OperationContext跟踪请求并使用OperationContext中采用的适当方法重载,则在OperationContext的最后结果中也可以使用相同的信息。

We will look at changing the error message in the future so it is less confusing. 我们将在将来着眼于更改错误消息,以减少混乱。 Thanks for the feedback! 感谢您的反馈!

in my case it got resolved for the error. 就我而言,它已经解决了错误。 ' Microsoft.WindowsAzure.Storage.StorageException: 'Element 0 in the batch returned an unexpected response code ' ' Microsoft.WindowsAzure.Storage.StorageException:'批处理中的元素0返回了意外的响应代码 '

code snippet 程式码片段

table.CreateIfNotExists(); table.CreateIfNotExists();

Main Code 主要代号

CloudStorageAccount SA = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("SC")); CloudStorageAccount SA = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(“ SC”));

CloudTableClient tableClient = SA.CreateCloudTableClient(); CloudTableClient tableClient = SA.CreateCloudTableClient();

CloudTable table = tableClient.GetTableReference("myWorld"); CloudTable表= tableClient.GetTableReference(“ myWorld”);

table.CreateIfNotExists(); table.CreateIfNotExists();

TableBatchOperation batchOperation = new TableBatchOperation(); TableBatchOperation batchOperation = new TableBatchOperation();

batchOperation.Insert(object); batchOperation.Insert(object);

table.ExecuteBatch(batchOperation); table.ExecuteBatch(batchOperation);

Another cause of this is the use of invalid characters in the key fields. 造成这种情况的另一个原因是在关键字段中使用了无效字符。 If you are googling this error message you might miss this answer: 如果您正在搜索此错误消息,则可能会错过以下答案:

Azure Table Storage RowKey restricted Character Patterns? Azure表存储RowKey受限制的字符模式?

Characters Disallowed in Key Fields The following characters are not allowed in values for the PartitionKey and RowKey properties: 键字段中不允许使用的字符PartitionKey和RowKey属性的值中不允许使用以下字符:

The forward slash (/) character 正斜杠(/)字符

The backslash () character 反斜杠()字符

The number sign (#) character 数字符号(#)字符

The question mark (?) character 问号(?)字符

Control characters from U+0000 to U+001F, including: 从U + 0000到U + 001F的控制字符,包括:

The horizontal tab (\\t) character 水平制表符(\\ t)

The linefeed (\\n) character 换行符(\\ n)

The carriage return (\\r) character 回车符(\\ r)

Control characters from U+007F to U+009F 从U + 007F到U + 009F的控制字符

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM