mongodb - Spring Data MongoDB 并发更新行为
问题描述
想象有一个包含单个字段的文档:{availableSpots: 100}
并且有数百万用户通过向 API 服务器发送请求来争夺一席之地。
每次请求到来时,服务器都会读取文档,如果 availableSpot > 0,则将其减 1,并在另一个集合中创建预订。
现在我读到,每当执行更新操作时,mongodb 都会锁定文档。
如果有一百万个并发请求会发生什么?是否会因为同一个文档一直被锁定而需要很长时间?此外,服务器在尝试更新文档之前读取文档的值,并且在它获取锁时,该位置可能不再可用。
线程也有可能在同一时刻获得“availableSpot > 0”,但实际上availableSpot 可能不足以满足所有请求。如何处理?
解决方案
这里最重要的是原子性和并发性。
1. 原子性
如果 availableSpots > 0 ,您的更新操作(减一):
db.collection.updateOne({"availableSpots" :{$gt : 0}}, { $inc: { availableSpots: -1 })
是原子的。
$inc 是单个文档中的原子操作。
参考:https ://docs.mongodb.com/manual/reference/operator/update/inc/
2.并发 由于MongoDB对写操作有文档级别的并发控制。每次更新都会锁定文档。
现在你的问题:
如果有一百万个并发请求会发生什么?
是的,每次更新都会一个一个地执行(由于锁定),因此会变慢。
服务器在尝试更新文档之前读取文档的值,并且在它获取锁时,该位置可能不再可用。
由于操作是原子的,因此不会发生这种情况。它将按您的意愿工作,仅执行 100 次更新,受影响的行数大于 0 或等于 1。
推荐阅读
- css - CSS 媒体查询和移动
- c++ - C++ 代码在编译过程中因错误分段错误而停止
- javascript - 如何从 Express Server 中的不同文件夹加载 API 端点?
- neo4j - neo4j neosemantics:加载模型约束
- python - Matplotlib 散点图中的分组值
- classification - weka 对输出的简单逻辑回归解释
- c# - 如何生成 sql 命令以使用其他列更新主键
- node.js - TypeError:Joi.validate 不是节点 js 中的函数
- python - 尽管文件不仅仅是换行符,但从 .docx 文件中读取会产生换行符
- python - 以可理解的形式重写 for 循环