我对 cosmos DB 相当陌生,并试图了解azure cosmos DB SDK 为 Java 提供的用于修补文档的增量操作。我需要在容器中的文档之一中维护增量计数器。该文件看起来像这样——
{"counter": 1}
现在,在我的应用程序中,每次发生操作时,我希望将此计数器的值增加 1。为此,我使用CosmosPatchOperations。我在这里添加一个增量,这样cosmosPatch.increment("/counter", 1)效果很好。
现在,该应用程序可以运行多个实例,所有实例都与 Cosmos 容器中的同一文档进行通信。所以App1和App2都可以同时触发增量。SDK 方法返回更新后的文档,我需要使用该更新后的值。
我的问题是,这里的 cosmos DB 是否采用某种锁定机制来确保两个补丁相继发生,并且在这种情况下,我在 App1 和 App2 中获得的更新值是什么(SDK 方法返回更新后的值)文档)。其中一个是 2 个,另一个是 3 个吗?
Couchbase 在集群级别支持这样的计数器,如此处所述,它对我来说工作得很好,没有任何并发问题。我现在正在迁移到 cosmos Db,并一直在努力寻找如何实现这一目标。
更新1:
我决定测试一下。我在本地 Mac 中设置了 Cosmos 模拟器,并创建了一个 DB 和容器,并且 RU 会自动从 1 增加到 10K。然后在这个容器中我添加了一个像这样的文档 -
{
"id": "randomId",
"counter": 0
}
在此之后,我创建了一个简单的 API,其职责只是在每次调用时将计数器加 1。然后我使用Locust多次调用这个 API 来模拟一个小型的类似负载的场景。最初,测试运行良好,每次调用都像预期的那样接收计数器(以增量方式)。在增加负载时,我看到一些错误,即RequestTimeOutException,状态代码为 408。其他请求仍然可以正常工作,并获得正确的计数器值。我不明白是什么导致了这里的 RequestTimeOut 异常。堆栈跟踪暗示与并发有关,但我无法理解它。这是堆栈跟踪 -
更新 2: 更新 …
我一直在使用 Spring,遇到了 spring 提供的 @DirtiesContext 注释。当您想在运行每个方法之前刷新应用程序上下文时(当然以牺牲性能为代价),在每个方法上使用它是有意义的,但是使用@DirtiesContext注释测试类究竟意味着什么?一个例子会非常有帮助。