[英]Using `mongoose transactions` when saving message in two collections in mongodb
If the student sends a message to the teacher, the message is saved in the teachers
and students
collections.如果学生向老师发送消息,则消息保存在
teachers
students
中。 The same situation is when a teacher sends a message to the student, they are also save in the two collections teachers
and students
.同样的情况是当老师给学生发消息时,他们也被保存在两个collections
teachers
和students
中。 How can I apply mongoose transaction
in the following code so that the message is saved in two collections.I don' want a situation that the message will be saved in one collection and in the other collection will not be saved due to an error.如何在以下代码中应用
mongoose transaction
,以便将消息保存在两个 collections 中。我不希望消息将保存在一个集合中而另一个集合中由于错误而不会保存的情况。 I am asking for help and clues我正在寻求帮助和线索
const express = require('express');
const mongoose = require('mongoose');
require('dotenv').config();
//const app = express();
// Connect to our Database and handle an bad connections
module.exports.db = mongoose
.createConnection(process.env.DATABASE, {
useNewUrlParser: true,
useFindAndModify: false,
useUnifiedTopology: true,
useCreateIndex: true
}
);
//controller
const db = require('./connection');
const session = db.startSession();
session.startTransaction();
module.exports.sendMessage = (req, res) => {
let {sender, receiver, msg, role} = req.body;
var hex = /[0-9A-Fa-f]{6}/g;
sender = (hex.test(sender))? mongoose.Types.ObjectId(sender) : sender;
receiver = (hex.test(receiver))? mongoose.Types.ObjectId(receiver) : receiver;
console.log(sender, receiver, msg, 'send');
if(role === 'tutor') {
let teacherMessage = new TeacherMessageSchema.TeacherMessageSchema({
contentInfo : {
msg : msg
},
sender : sender
})
let studentMessage = new TeacherMessageSchema.TeacherMessageSchema({
contentInfo : {
msg : msg
},
receiver : receiver
})
db.db.collection('teachers').findOneAndUpdate(
{ _id : receiver },
{ $push: { messages: teacherMessage } },
(err, updated) => {
console.log(updated, 'vvv');
updated.value.hashed_password = undefined;
updated.value.salt = undefined;
if(err) {
res.status(404).json(err);
}
if (updated) {
res.status(200).json(updated.value);
db.db.collection('students').findOneAndUpdate(
{ _id : sender },
{ $push: { messages: studentMessage } },
);
}
}, session(session)
)
}
if(role === 'student') {
let studentMessage = new StudentMessageSchema.StudentMessageSchema({
contentInfo : {
msg : msg
},
receiver : receiver
})
let teacherMessage = new TeacherMessageSchema.TeacherMessageSchema({
contentInfo : {
msg : msg
},
sender : sender
})
db.db.collection('students').findOneAndUpdate(
{ _id : sender },
{ $push: { messages: studentMessage } },
(err, updated) => {
console.log(updated, 'sss');
updated.value.hashed_password = undefined;
updated.value.salt = undefined;
if(err) {
res.status(404).json(err);
}
if (updated) {
res.json(updated.value);
db.db.collection('teachers').findOneAndUpdate(
{ _id : receiver },
{ $push: { messages: teacherMessage } },
)
}
},
), session(session)
}
}
Logged variable db记录的变量 db
{
db: NativeConnection {
base: Mongoose {
connections: [Array],
models: [Object],
modelSchemas: [Object],
options: [Object],
_pluralize: [Function: pluralize],
plugins: [Array]
},
collections: {},
models: {},
config: { autoIndex: true },
replica: false,
options: null,
otherDbs: [],
relatedDbs: {},
states: [Object: null prototype] {
'0': 'disconnected',
'1': 'connected',
'2': 'connecting',
'3': 'disconnecting',
'99': 'uninitialized',
disconnected: 0,
connected: 1,
connecting: 2,
disconnecting: 3,
uninitialized: 99
},
_readyState: 1,
_closeCalled: false,
_hasOpened: true,
_listening: false,
_connectionOptions: {
useNewUrlParser: true,
useFindAndModify: false,
useUnifiedTopology: true,
useCreateIndex: true,
promiseLibrary: [Function: Promise]
},
client: MongoClient {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
s: [Object],
topology: [ReplSet],
[Symbol(kCapture)]: false
},
name: null,
'$initialConnection': Promise { [Circular] },
db: Db {
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
s: [Object],
serverConfig: [Getter],
bufferMaxEntries: [Getter],
databaseName: [Getter],
[Symbol(kCapture)]: false
}
}
}
I have added in the code Anytime there is an error:我在代码中添加了任何时候出现错误:
await session.abortTransaction();等待 session.abortTransaction();
Otherwise (happy path) commit the changes.否则(快乐路径)提交更改。
await session.commitTransaction();等待 session.commitTransaction();
Abort and commit are Promise base functions, so I have changed the functions where they were used as async. Abort 和 commit 是 Promise 基本函数,所以我更改了它们用作异步的函数。
const express = require('express');
const mongoose = require('mongoose');
require('dotenv').config();
//const app = express();
// Connect to our Database and handle an bad connections
module.exports.db = mongoose
.createConnection(process.env.DATABASE, {
useNewUrlParser: true,
useFindAndModify: false,
useUnifiedTopology: true,
useCreateIndex: true
}
);
//controller
const db = require('./connection');
module.exports.sendMessage = async (req, res) => {
const session = await db.startSession();
session.startTransaction();
let {sender, receiver, msg, role} = req.body;
var hex = /[0-9A-Fa-f]{6}/g;
sender = (hex.test(sender))? mongoose.Types.ObjectId(sender) : sender;
receiver = (hex.test(receiver))? mongoose.Types.ObjectId(receiver) : receiver;
console.log(sender, receiver, msg, 'send');
if(role === 'tutor') {
let teacherMessage = new TeacherMessageSchema.TeacherMessageSchema({
contentInfo : {
msg : msg
},
sender : sender
})
let studentMessage = new TeacherMessageSchema.TeacherMessageSchema({
contentInfo : {
msg : msg
},
receiver : receiver
})
db.db.collection('teachers').findOneAndUpdate(
{ _id : receiver },
{ $push: { messages: teacherMessage } },
async (err, updated) => {
console.log(updated, 'vvv');
updated.value.hashed_password = undefined;
updated.value.salt = undefined;
if(err) {
await session.abortTransaction();
res.status(404).json(err);
return
}
if (updated) {
res.status(200).json(updated.value);
db.db.collection('students').findOneAndUpdate(
{ _id : sender },
{ $push: { messages: studentMessage } },
);
}
}, session(session)
)
}
if(role === 'student') {
let studentMessage = new StudentMessageSchema.StudentMessageSchema({
contentInfo : {
msg : msg
},
receiver : receiver
})
let teacherMessage = new TeacherMessageSchema.TeacherMessageSchema({
contentInfo : {
msg : msg
},
sender : sender
})
db.db.collection('students').findOneAndUpdate(
{ _id : sender },
{ $push: { messages: studentMessage } },
async (err, updated) => {
console.log(updated, 'sss');
updated.value.hashed_password = undefined;
updated.value.salt = undefined;
if(err) {
await session.abortTransaction();
res.status(404).json(err);
return;
}
if (updated) {
res.json(updated.value);
db.db.collection('teachers').findOneAndUpdate(
{ _id : receiver },
{ $push: { messages: teacherMessage } },
)
}
},
session(session)
)
}
await session.commitTransaction();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.