use*_*934 5 concurrency mongodb mongodb-java
假设有一个包含单个字段的文档:{availableSpots: 100}
数以百万计的用户竞相通过向 API 服务器发送请求来获得席位。
每次收到请求时,服务器都会读取文档,如果 availableSpot > 0,则会将其减 1 并在另一个集合中创建预订。
现在我读到每当执行更新操作时 mongodb 都会锁定文档。
如果有一百万个并发请求会发生什么?是否会因为同一个文档不断被锁定而需要很长时间?此外,服务器在尝试更新文档之前会读取文档的值,并且当它获取锁时,该位置可能不再可用。
线程也有可能在同一时刻获得“availableSpot > 0”为真,但实际上,availableSpot 可能不足以满足所有请求。这该如何处理呢?
这里最重要的是原子性和并发性。
1. 原子性
如果 availableSpots > 0 则更新操作(减一):
db.collection.updateOne({"availableSpots" :{$gt : 0}}, { $inc: { availableSpots: -1 })
Run Code Online (Sandbox Code Playgroud)
是原子的。
$inc 是单个文档中的原子操作。
参考: https: //docs.mongodb.com/manual/reference/operator/update/inc/
2.并发性 由于MongoDB对写操作有文档级的并发控制。每次更新都会锁定文档。
现在你的问题:
如果有一百万个并发请求会发生什么?
是的,每次更新都将一一执行(由于锁定),因此速度会变慢。
服务器在尝试更新文档之前读取文档的值,并且当它获取锁时,该位置可能不再可用。
由于操作是原子的,因此不会发生这种情况。它将按照您的意愿工作,仅执行 100 次更新,且受影响的行数大于 0 或等于 1。