C# CosmosDb-写入操作导致错误。误差=16500

C# CosmosDb-写入操作导致错误。误差=16500,c#,mongodb,azure,azure-cosmosdb,polly,C#,Mongodb,Azure,Azure Cosmosdb,Polly,我在CosmosDB上有一个使用MongoDB的数据库 以下是我使用Polly的重试模式: _retryPolicy = Policy .Handle<MongoCommandException>(e => { if (e.Code != 16500 /*(RateLimitCode)*/ || !(e.Result is BsonDocument bsonDocument)) { return false

我在CosmosDB上有一个使用MongoDB的数据库

以下是我使用Polly的重试模式:

_retryPolicy = Policy
    .Handle<MongoCommandException>(e =>
    {
        if (e.Code != 16500 /*(RateLimitCode)*/ || !(e.Result is BsonDocument bsonDocument))
        {
            return false;
        }

        if (bsonDocument.TryGetValue("StatusCode", out var statusCode) && statusCode.IsInt32)
        {
            switch (statusCode.AsInt32)
            {
                case 429: //HttpThrottleErrorCode
                case 1: //HttpServiceIsUnavailable
                case 50: //HttpOperationExceededTimeLimit:
                    return true;
                default:
                    return false;
            }
        }

        return true;
    })
    .Or<MongoConnectionException>()
    .WaitAndRetryAsync(2, i => TimeSpan.FromSeconds(MongoRepositoryConstants.RETRY_POLICY_TIME_OUT_IN_SECOND));
不幸的是,我在CosmosDb上遇到了以下问题:

写入操作导致错误。Error=16500,RetryAfterMs=12,Details='大容量写入操作导致一个或多个错误。Error=16500,RetryAfterMs=12,Details='
MongoDB.Driver.MongoBulkWriteException`1[[MongoDB.Bson.BsonDocument,MongoDB.Bson,Version=2.8.1.0,Culture=neutral,PublicKeyToken=null]]

根据以下文档,我知道16500错误代码是数据库上RU/sec的问题。但是它是一个
MongoBulkWriteException
,所以我想知道它是否由重试策略处理

在以下文档中,
MongoBulkWriteException
不是从
MongoCommandException
继承的。因此,您能否确认Polly重试策略在这种情况下不适用

编辑:查看Azure上的CosmosDb仪表板,它看起来像是
更新手册
花费了很多RU:

我们目前正在为MongoDB用户的服务器端重试新功能运行私有预览,我认为这将有助于您在这里所做的工作

其工作原理是,当遇到429请求时,我们将在返回用户之前自动重试请求,最长时间为60秒。我们的测试表明,这几乎解决了客户在使用MongoDB客户机进行批量接收或使用mongoimport等工具时看到的所有问题

如果您有兴趣参与此私人预览,请在我的Twitter个人资料markjbrown上为我发送DM,并提供您的电子邮件地址和Cosmos DB帐户名,以便我们为您启用此功能


谢谢。

回答您的问题,是的,此策略不会处理批量写入期间的限制错误

您需要另外处理
MongoBulkWriteException
。然后,您应该查看此异常的内容,迭代
WriteErrors
集合,检查特定元素是否因节流而出错,并安排重试(理想情况下,从此类失败记录组成新的批量写入集合)

public async Task<bool> UpdateManyAsync(IEnumerable<JObject> listRelatedQuotes, DateTime datetime, string quoteStatus)
{
    var listQuoteNumber = new BsonArray(listRelatedQuotes.Select(quote => quote[StdJsonDataLabel.toto][StdJsonDataLabel.QUOTE_IDENTIFIER_LABEL].ToString()));
    FilterDefinition<BsonDocument> filter = Builders<BsonDocument>.Filter.In(StdJsonDataPath.toto, listQuoteNumber);

    var update = Builders<BsonDocument>.Update.Set(StdJsonDataPath.fooooo, datetime.ToString("o"));

    if (!string.IsNullOrEmpty(quoteStatus))
    {
        update = update.Set(StdJsonDataPath.foooo2, quoteStatus);
    }

    bool res = false;
    await _retryPolicy.ExecuteAsync(async () =>
    {
        var result = await _collection.UpdateManyAsync(filter, update).ConfigureAwait(false);
        res = (result.MatchedCount > 0);
    });
    return res;
}