【问题标题】:Concurrency issue with CosmosDbCosmosDb 的并发问题
【发布时间】:2020-01-02 19:47:44
【问题描述】:

我们正在努力解决由于竞争条件而创建的重复文档。我们处理事件并创建或更新文档。我们注意到,如果我们在几毫秒内收到两个事件,我们正在创建重复的文档。第一个事件应该生成新文档,第二个事件应该是更新。

这是我们在存储产品中的逻辑。

  1. 查找具有特定 ID 和状态的现有文档
  2. 创建新文档或更新现有文档(如果存在)。
  3. 如果创建,我们再做一次选择,以检查我们是否只有一个带有 id 和 status 组合的文档。如果大于 1,则回滚。在更新的情况下,我们依赖 Etag。

我们对更新很好,但创建给我们带来了困难。让我知道是否有办法解决它。 Deduplicate key 是外部 id 和状态的组合。我们有一个现有的数据库,我们希望避免任何需要创建新数据库的更改。

谢谢, 罗希特

【问题讨论】:

  • 您使用的是哪种一致性级别?
  • 一致前缀

标签: c# .net azure concurrency azure-cosmosdb


【解决方案1】:

定义一个unique key。 CosmosDB 将防止插入指定唯一的重复键。然后,您可以捕获异常并执行更新逻辑。

根据反馈进行修改

我假设您处于一个有多个线程或进程正在执行此逻辑的环境中。当您尝试处理每个文档时,您将需要一个关键部分(锁)。当需要与 CosmosDB 进行交互时,您需要获取对要插入/更新的文档的 ID 的锁定。然后,您可以检查文档是否存在,并根据结果进行插入或更新。然后您将通过释放锁来退出临界区。

根据您使用的技术,您可以使用哪些技术。如果它是 Azure 函数的单个实例,则可以使用静态 ThreadSafeDictionary 之类的东西进行锁定。如果它是多个 Azure Functions 或 Web 应用程序,则需要一个分布式锁。有多种方法可以执行此操作,例如 Azure Blob 租约。

我不知道 CosmosDB 中有任何类型的同步功能可用 OOTB。

【讨论】:

  • 谢谢 Rob,我们有一个现有的数据库,我们希望避免创建一个具有唯一约束的新数据库。这将是一项重大的努力。我错过了问题中的这一部分。
  • @RohitRanjan 我已经详细说明了我的答案。
  • 非常感谢您的时间 Rob,不幸的是,任何关键部分都会破坏可伸缩性和性能。我们正在使用服务结构。此服务托管在跨地理位置的多个集群上。
  • 在该策略下,关键部分将基于每个 ID。所以你的锁定将是最小的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多