为什么DocumentDb在测试场景中运行时偶尔会失败

Dam*_*amo 8 c# azure azure-cosmosdb

我们有一个目前正在开发的项目,我们使用Azure DocumentDb作为数据存储库.它一直很好,我真的很喜欢它如何工作以及它如何实现快速开发,但最近我们的集成测试已经开始失败.

每次测试运行时,我们的集成测试都会在数据库中创建和拆除集合.我想知道它的这个过程是否以某种方式"破坏"了数据库.

我已经将我们的项目剥离到了它的骨架并在这里检查了它:https://github.com/DamianStanger/DocumentDbDemo

当我运行测试时,我收到以下错误:

System.AggregateException : One or more errors occurred.
  ----> Microsoft.Azure.Documents.DocumentClientException : Message:  {"Errors":["Resource with specified id or name already exists"]}
ActivityId: e273b9d6-b571-43d3-9802-c7d7c819a3f0, Request URI: /apps/c9c8f510-0ca7-4702-aa6c-9c596d797367/services/507e2a70-c787-437c-9587-0ff4341bc265/partitions/ae4ca317-e883-4419-84f9-c8d053ffc73d/replicas/131159218637566393p
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Wait()
   at DocumentDbDemo.Data.AggregateRepository.CreateCollectionIfNotExists() in K:\_code\VisualStudio\DocumentDbPerfTests\DocumentDbDemo.Data\AggregateRepository.cs:line 32
   at DocumentDbDemo.Data.AggregateRepository..ctor(ConfigFactory configFactory) in K:\_code\VisualStudio\DocumentDbPerfTests\DocumentDbDemo.Data\AggregateRepository.cs:line 19
   at DocumentDbDemo.Data.Tests.AggregateRepositoryTests.ShouldReturnNullIfNotFound() in K:\_code\VisualStudio\DocumentDbPerfTests\DocumentDbDemo.Data.Tests\AggregateRepositoryTests.cs:line 24
--DocumentClientException
Run Code Online (Sandbox Code Playgroud)

AggregateRepository.cs_client.ReadDocumentCollectionAsync内的调用失败引起的.我不明白.代码中的异常是首先检查集合是否存在(它确实存在),然后如果不存在则会创建它.显然,创建将失败,因为集合存在!

第二种类型的失败是:

System.AggregateException : One or more errors occurred.
  ----> Microsoft.Azure.Documents.DocumentClientException : Message: {"Errors":["Owner resource does not exist"]}
ActivityId: 9e25516a-25fe-4bf3-a88d-6234c76ac47d, Request URI: /apps/c9c8f510-0ca7-4702-aa6c-9c596d797367/services/507e2a70-c787-437c-9587-0ff4341bc265/partitions/ae4ca317-e883-4419-84f9-c8d053ffc73d/replicas/131159551041924002s
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Wait()
   at DocumentDbDemo.Data.Tests.AggregateRepositoryTests.ShouldSaveNewAggregate(AggregateRepository aggregateRepository) in K:\_code\VisualStudio\DocumentDbPerfTests\DocumentDbDemo.Data.Tests\AggregateRepositoryTests.cs:line 48
   at DocumentDbDemo.Data.Tests.AggregateRepositoryTests.ShouldSaveAndReadTheDocument() in K:\_code\VisualStudio\DocumentDbPerfTests\DocumentDbDemo.Data.Tests\AggregateRepositoryTests.cs:line 42
--DocumentClientException
Run Code Online (Sandbox Code Playgroud)

这同样令人费解,该集合再次存在,但文档没有,我们是第一次使用唯一的GUID创建它.代码失败的是在AggregateRepository.cs_client.UpsertDocumentAsync类中再次调用

再生产

我使用前面提到的github repo中的代码重复了很多次,但是,使用了特定的documentDb数据库和集合.当我切换到另一个全新的DB时,代码和测试按预期工作!

这就是我认为我们如何使用特定数据库的原因.这个项目现在已经有几个星期了,所有的测试都运行得很好,直到昨天他们真的开始偶尔失败了.有时两者都是绿色,或者一个或两个都会失败.

如果我们一遍又一遍地创建和删除一个特定的集合,可能是很多次,我的问题就是documentDb的问题?或者,如果你这样做,是否有已知的失败案例?

我当然可以把我们的测试数据库收起来,创建另一个并埋头,希望它是一次性的.但这可能发生在prod?我真的想深究这一点.是否有可能看到'破碎'的内部状态!DB以任何方式?

注意:

即使我在测试类中注释掉/删除了clean函数,我现在也会失败.所以我不认为它是async和await的问题,并且在读/写完成之前删除了集合.

另请注意,在我的实际项目中,我们不会像测试类中那样进行循环,这对我(以及您?)来说很容易多次运行测试直到失败.(它不适用于您可能拥有的新数据库!)

小智 2

我认为问题源于 Cosmos 的一致性级别(请参见此处)。基本上,Cosmos 数据库有一些您正在访问的本地实例(通过半负载均衡器)。发生的情况(在默认一致性模型中)是您正在执行更新,它最终会写入所有节点。

如果您想确保读取不会失败,您需要使用强一致性模型,或者使用会话并在后续读取时发送会话令牌