【问题标题】:MongoDb concurrency best practicesMongoDb 并发最佳实践
【发布时间】:2020-06-19 10:34:04
【问题描述】:

我是 MongoDb 的新手,我正在创建一个应用程序来管理一个非常大的项目(资源)列表,并且该应用程序应该为每个资源管理一种预订。

我的想法是在资源文档中嵌入预订文档,为了避免并发问题我需要在预订过程中锁定资源。

我看到 MongoDB 允许在集合级别锁定,但这会对预订功能造成瓶颈,因为在当前预订正在进行之前,将查看集合中的所有资源,因此对于大量用户和大量的资源,此解决方案的性能将很差。 除此之外,如果预订资源发生死锁,所有资源都将被锁定。

是否有其他解决方案或最佳实践来提高此用例的性能和可扩展性? 一个可能的解决方案应该是锁定不是在集合级别,而是在文档级别(我的示例中的资源),这样预订资源的用户不会锁定另一个用户预订另一个资源,即使(也在这个case)我不确定最终结果,因为写入命令不是并行执行的:我想我可能还需要一个服务器集群来并行管理多个写入。

【问题讨论】:

标签: mongodb concurrency locks


【解决方案1】:

你是绝对正确的,你绝对不应该仅仅为了更新一个文档而锁定整个集合。

现在这个问题取决于您如何更新您的文档。 如果您使用单个更新查询更新您的文档,那么由于文档更新是原子的,您将没有问题。

但是如果你首先必须阅读文档,更改文档,保存文档,那么你就会遇到并发问题。就在您保存更改的文档之前,它可能会被其他请求更新,并且您阅读的文档将不再是最新的,因此您的新更新也将不正确。

解决这个并发问题的简单方法是在每个文档中存储一个版本号(通常是_v)。对于每次更新,您都会增加版本号。然后,每次您进行读取、更改和更新时,请确保您读取的文档版本与数据库中该文档的版本相同。当版本号不同时,更新将失败,您只需重试即可。

如果您使用node.js,那么您可能正在使用mongoosemongoose 将生成_v 并在后台进行并发检查。所以您不必做任何额外的工作来解决这个并发问题。

【讨论】:

  • 我的具体情况是一种资源预订,这是read doc然后write的情况,所以并发是可以的。我想使用EF Core,所以我在.NET环境中,我希望.NET驱动程序像mangoose一样管理并发。感谢金的支持
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-14
  • 2018-11-27
  • 2011-01-12
  • 2016-07-10
相关资源
最近更新 更多