C# 与CosmosDb的并发问题

C# 与CosmosDb的并发问题,c#,.net,azure,concurrency,azure-cosmosdb,C#,.net,Azure,Concurrency,Azure Cosmosdb,由于竞争条件,我们正在努力处理创建的重复文档。我们处理事件并创建或更新文档。我们注意到,如果在几毫秒内得到两个事件,我们将创建重复的文档。第一个事件应生成新文档,第二个事件应为更新 这是存储产品中的逻辑 查找具有特定Id和状态的现有文档 创建新文档或更新现有文档(如果存在) 如果创建,我们将再次选择一个,以检查是否只有一个id和状态组合的文档。如果超过1,则回滚。在更新的情况下,我们依赖Etag 我们在更新方面做得很好,但create给了我们很多困难。如果有办法,请告诉我。 重复数据消除键是外部

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

这是存储产品中的逻辑

  • 查找具有特定Id和状态的现有文档
  • 创建新文档或更新现有文档(如果存在)
  • 如果创建,我们将再次选择一个,以检查是否只有一个id和状态组合的文档。如果超过1,则回滚。在更新的情况下,我们依赖Etag
  • 我们在更新方面做得很好,但create给了我们很多困难。如果有办法,请告诉我。 重复数据消除键是外部id和状态的组合。我们有一个现有的数据库,我们希望避免任何需要创建新数据库的更改

    谢谢, Rohit定义了一个。CosmosDB将防止插入指定为唯一的重复密钥。然后可以捕获异常并执行更新逻辑

    根据反馈进行编辑

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

    取决于您使用的技术,您可以选择哪些技术。如果它是Azure函数的单个实例,则可以使用静态ThreadSafeDictionary之类的工具进行锁定。如果是多个Azure功能或Web应用程序,则需要一个分布式锁。有几种方法可以做到这一点,例如Azure Blob租约


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

    您使用的是哪种一致性级别?一致性前缀谢谢您,我们有一个现有的数据库,我们希望避免创建具有唯一约束的新数据库。这将是一项重大努力。我错过了问题中的这一部分。@RohitRanjan我已经详细阐述了我的答案。非常感谢您的时间,Rob,不幸的是,任何关键部分都会破坏可扩展性和性能。我们正在使用服务结构。此服务位于地理位置的多个群集上。根据该策略,关键部分将基于每个id。因此,您的锁定将是最小的。