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

时间:2016-08-19 13:48:52

标签: 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

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 个答案:

答案 0 :(得分:2)

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

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