egg-mongoose 事务能否并发执行?

rta7y2nd  于 6个月前  发布在  Go
关注(0)|答案(1)|浏览(86)

我发现在同一个接口 不同的请求加入事务后,数据更新不是每次都成功,
以下是我的服务端代码

async del(body) {
const { ctx, app } = this;
const session = await app.mongoose.startSession({
//readPreference: { mode: 'primary' },
});
try {
const tool = new Tool();
const statusCode = new StatusCode();
let teacherNames = '';
await session.startTransaction({
readConcern: { level: 'snapshot' },
writeConcern: { w: 'majority' },
});
for (let i = 0; i < body.teacherIds.length; i++) {

let teacher = await app.model.RoleMap.findOne({_id: body.teacherIds[i]})
    if (teacher.role.indexOf("master") >= 0 || teacher.role.indexOf("admin") >= 0) {//  
      teacher = await app.model.RoleMap.findOneAndUpdate(
        { _id: body.teacherIds[i] },
        { $pull : { role : "teacher" }},
        { new: true, session :session }
      );
    }else{
      teacher = await app.model.RoleMap.findOneAndUpdate(
        { _id: body.teacherIds[i] },
        { state: 'deleted'},
        { new: true,session :session}
      );
    }
 
    const classes = await app.model.Class.find({teachers: body.teacherIds[i]});
    for (let j = 0; j < classes.length; j++) {
      let teachers = e.teachers;
      teachers = teachers.slice(j, 1);
      await app.model.Class.updateOne({_id: e._id}, {teachers},{ session });
    }
    if (body.teacherIds.length > 1) {
      teacherNames += `、${teacher.name}`
    } else {
      teacherNames = teacher.name;
    }
  }
  const admins = await app.model.RoleMap.find({
    role: {$in: ['admin', 'master']},
    state: 'available',
    school: body.school
  })
  const operator = await app.model.RoleMap.findOne({
    phone: body.phone,
    school: body.school
  })
  const msg = `已成功删除${teacherNames}老师信息`
  admins.forEach(e => {
    tool.pushMsg(String(e.teacher), msg)
  })
  await app.model.NotifyMsg.create([{
    title: '删除通知',
    // 消息内容
    content: msg,
    // 处理人
    operator: operator._id,
    // 消息种类,删除: del, 续费:pay,报名:regist,奖学金:reward, 课程: course, 签到:sign,
    // 点评: comment, 作业:homework,课时费: courseFee, 请假: dayOff, sticker: sticker
    kind: 'del',
    // 消息类型: 管理员端: admin, 老师端: teacher, 家长端:parent
    type: 'admin',
    school: body.school
  }],{session});

  await session.commitTransaction(); // 提交事务
  return statusCode.success;
} catch(err) {
  await session.abortTransaction(); // 回滚
  app.logger.error(`\x1B[41;37m ERROR: TeacherService,del \x1B[0m ${err}---${err.stack}`);
  return { code: 500, msg: 'server error', result: false };
}finally{
  await session.endSession(); // 结束
}

}

###########
测试代码如下 test.js
// 模拟同时删除两个不同的老师
var fs = require('fs'),
request = require('request');
//var host = 'localhost';

var host = 'edu.brmind.cn'
var opt = {
method:'POST',
url: https://${host}/api/role/del ,
json:true,
body: {"teacherIds":["5d3d067ce4a51b0394b89b7b"]},
}

var opt1 = {
method:'POST',
url: https://${host}/api/role/del ,
json:true,
body: {"teacherIds":["5d3d08a1fff42c04d641ebda"]},
}

// 请求 0
request(opt,(err,res,body)=>{
if(err){
console.log(err);
return;
}
console.log(body);
console.log(res.headers);
});
// 请求 1
request(opt1,(err,res,body)=>{
if(err){
console.log(err);
return;
}
console.log(body);
console.log(res.headers);
});

我发现,又时候能成功删除一个老师,又时候2个都删不掉,
是否我的用法又问题,mongoose有相关的设置我没用对?
谢谢解答

相关环境信息

  • 操作系统:centos 7
  • Node 版本: v11.14.0
  • Egg 版本: 2.21.1
r7knjye2

r7knjye21#

mongoose 能怎么样就怎么样,egg 只是简单的一个包装,可以看下对应的 mongoose 类库去。

PS:学会用 Markdown 的 code 排版

相关问题