首页 文章

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

提问于
浏览
8

我们有一个目前正在开发的项目,我们使用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

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

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

再现

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

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

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

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

注意:

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

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

1 回答

  • 2

    我认为问题源于宇宙的一致性水平(见here) . 基本上,Cosmos数据库有一些您正在访问的本地实例(通过半负载均衡器) . 发生的事情(在默认一致性模型中)是您正在执行更新,它将 eventually 写入所有节点 .

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

相关问题