egg
egg copied to clipboard
egg-mongoose 事务能否并发执行?
我发现在同一个接口 不同的请求加入事务后,数据更新不是每次都成功, 以下是我的服务端代码
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
mongoose 能怎么样就怎么样,egg 只是简单的一个包装,可以看下对应的 mongoose 类库去。
PS:学会用 Markdown 的 code 排版