本文介绍了mongodb并发插入文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我们目前有两个集合: Teachers Students ,我们限制每个老师最多只能拥有 30 个学生,当然我有已经在每个文档上设置了一个参考键,例如 studentsId teachersId .

Says we currently have two collections: Teachers and Students, we limit each teacher can only owns up to 30 students, surely I have already set a reference-key like studentsId, teachersId on each document.

当我要创建一个新学生时,如何确保仅在指定的老师少于30名学生时创建它?

When I'm about to create a new Student, how can I make sure I only create it when the specify teacher has less than 30 students?

// get students count under specify teacher
const StudentNums = await Teachers.findById(1234).studentsId.length;
if (StudentNums < 30) /* create student */

(以上代码是用JS编写的)

(above code is written JS)

毫无疑问,以上代码在并发时会失败,导致mongodb共享读取锁,有什么想法吗?提前发短信.

undoubtedly above code would fail when concurrency, cause mongodb share read locks, any ideas? tks in advance.

推荐答案

为什么不处理与并发相关的任何事情,为什么不仅仅检查您的老师是否可以容纳更多学生呢?您可以通过一次操作进行检查和更新,以确保原子性.

Instead of handling anything related to concurrency, why not just check if your teacher can accomodate any more students ? You can check and update in a single operation to ensure atomicity.

本质上可以归结为在查找查询中添加学生长度检查,如下所示:

It essentially boils down to adding student length check in find query like below :

teachers.update({id: 1, '$where': 'this.students.length < 8'}, {'$push': {students: 8}}

在下面添加了一个测试用例:

Added a test case below:

 const mongodb = require('mongodb')
 const mongoClient = mongodb.MongoClient

 mongoClient.connect('mongodb://localhost:27017/stackoverflow', function (err, db) {
   if (err) {
     console.log(`DB connect error ${JSON.stringify(err)}`)
   } else {
     const teachers = db.collection('teachers')
     let doc = {id: 1, name: 'Ms Anderson', students: [1, 2, 3, 4, 5, 6, 7], subject: 'Matrix'}
     teachers.insert(doc, {w: 1}, function (err, result) {
       console.log(`insert error ${JSON.stringify(err)}`)
       console.log(`insert result : ${JSON.stringify(result)}`)
//Check the $where parameter, it will return only if student array has size less than 8
       teachers.update({id: 1, '$where': 'this.students.length < 8'}, {'$push': {students: 8}}, {w: 1}, function (err, result) {
         console.log(`update error ${JSON.stringify(err)}`)
         console.log(`update result : ${JSON.stringify(result)}`)
       })
     })
   }
 })

如果文档已更新,则

结果为1,否则为0.

result is 1 if document is updated else 0.

这篇关于mongodb并发插入文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 10:08