插入文档时的mongodb并发性

插入文档时的mongodb并发性,mongodb,concurrency,Mongodb,Concurrency,说我们目前有两个集合:教师和学生,我们限制每个教师最多只能拥有30名学生,当然我已经在每个文档上设置了一个参考键,如学生SID,教师SID 当我准备创建一个新学生时,如何确保我只在指定的老师少于30名学生时创建它 // get students count under specify teacher const StudentNums = await Teachers.findById(1234).studentsId.length; if (StudentNums < 30) /* cr

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

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

// get students count under specify teacher
const StudentNums = await Teachers.findById(1234).studentsId.length;
if (StudentNums < 30) /* create student */
//获取指定教师下的学生数
const StudentNums=等待教师。findById(1234)。studentsId.length;
如果(StudentNums<30)/*创建学生*/
(上面的代码是用JS编写的)

毫无疑问,上述代码在并发时会失败,导致mongodb共享读锁,有什么想法吗?tks。您可以在应用程序级别应用标准

假设教师集合中的文档具有以下字段:

db.teachers.insert({
    _id: 1234,
    students: [12,34],
    version: 8
});
其中,
\u id
student
是对象的有效负载,
version
是并发控制的内部字段。问题中的更新可能如下所示:

var teacher = db.teachers.findById(1234);

if(teacher.students.length < 30) {
    var res = db.teachers.update({_id: 1234, version: teacher.version}, {$push: {students: 56}, $inc: {version: 1}});
}

if(res.nModified < 1) {
    // apply retry logic
}
var-teacher=db.teachers.findById(1234);
如果(教师.学生.长度<30){
var res=db.teachers.update({u id:1234,版本:teacher.version},{$push:{students:56},$inc:{version:1}});
}
if(res.nModified<1){
//应用重试逻辑
}
如果发生并发更新,数据库中文档的版本将与更新的查询部分不匹配,这将导致0个文档更新

您可以在应用程序级别应用标准

假设教师集合中的文档具有以下字段:

db.teachers.insert({
    _id: 1234,
    students: [12,34],
    version: 8
});
其中,
\u id
student
是对象的有效负载,
version
是并发控制的内部字段。问题中的更新可能如下所示:

var teacher = db.teachers.findById(1234);

if(teacher.students.length < 30) {
    var res = db.teachers.update({_id: 1234, version: teacher.version}, {$push: {students: 56}, $inc: {version: 1}});
}

if(res.nModified < 1) {
    // apply retry logic
}
var-teacher=db.teachers.findById(1234);
如果(教师.学生.长度<30){
var res=db.teachers.update({u id:1234,版本:teacher.version},{$push:{students:56},$inc:{version:1}});
}
if(res.nModified<1){
//应用重试逻辑
}

如果发生并发更新,数据库中文档的版本将与更新的查询部分不匹配,这将导致0个文档更新

与其处理任何与并发相关的事情,不如检查一下你的老师是否能容纳更多的学生?您可以在单个操作中进行检查和更新,以确保原子性

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

teachers.update({id: 1, '$where': 'this.students.length < 8'}, {'$push': {students: 8}}
teachers.update({id:1,$where':'this.students.length<8'},{'$push':{students:8}
在下面添加了一个测试用例:

 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)}`)
       })
     })
   }
 })
const mongodb=require('mongodb'))
const mongoClient=mongodb.mongoClient
mongoClient.connect('mongodb://localhost:27017/stackoverflow,函数(err,db){
如果(错误){
log(`DB connect error${JSON.stringify(err)}`)
}否则{
const teachers=db.collection(“教师”)
让doc={id:1,名字:'msanderson',学生:[1,2,3,4,5,6,7],主题:'Matrix'}
insert(doc,{w:1},函数(err,result){
log(`insert error${JSON.stringify(err)}`)
log(`insert result:${JSON.stringify(result)}`)
//选中$where参数,仅当学生数组的大小小于8时,它才会返回
update({id:1,$where':'this.students.length<8'},{'$push':{students:8},{w:1},函数(err,result){
log(`updateerror${JSON.stringify(err)}`)
log(`updateresult:${JSON.stringify(result)}`)
})
})
}
})

如果文档被更新,则结果为1,否则为0。

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

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

teachers.update({id: 1, '$where': 'this.students.length < 8'}, {'$push': {students: 8}}
teachers.update({id:1,$where':'this.students.length<8'},{'$push':{students:8}
在下面添加了一个测试用例:

 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)}`)
       })
     })
   }
 })
const mongodb=require('mongodb'))
const mongoClient=mongodb.mongoClient
mongoClient.connect('mongodb://localhost:27017/stackoverflow,函数(err,db){
如果(错误){
log(`DB connect error${JSON.stringify(err)}`)
}否则{
const teachers=db.collection(“教师”)
让doc={id:1,名字:'msanderson',学生:[1,2,3,4,5,6,7],主题:'Matrix'}
insert(doc,{w:1},函数(err,result){
log(`insert error${JSON.stringify(err)}`)
log(`insert result:${JSON.stringify(result)}`)
//选中$where参数,仅当学生数组的大小小于8时,它才会返回
update({id:1,$where':'this.students.length<8'},{'$push':{students:8},{w:1},函数(err,result){
log(`updateerror${JSON.stringify(err)}`)
log(`updateresult:${JSON.stringify(result)}`)
})
})
}
})

result
如果文档更新为0,则结果为1。

为什么不使用回调?@BertrandMartel如果您的意思是我们获取教师的学生数,然后创建一个学生数,然后通过回调的方式进行创建,我想说的是abt线程,多个线程同时运行一段代码,然后它们获得相同的学生数并创建资源,而ch可能会导致错误的逻辑。@BertrandMartel此外,语法不会深入改变回调工作原理,你可以将其视为语法糖,像sync一样编写,但异步工作。为什么不使用回调?@BertrandMartel如果你的意思是我们得到老师的学生数,然后创建一个,用回调的方式来做,我会说我们在这里谈论abt线程s、 几个线程同时运行一段代码,然后它们得到相同的学生数,并创建可能导致错误逻辑的资源。@BertrandMartel此外,语法不正确