将消息保存在mongodb中的两个集合中时,使用“猫鼬交易" [英] Using `mongoose transactions` when saving message in two collections in mongodb

查看:52
本文介绍了将消息保存在mongodb中的两个集合中时,使用“猫鼬交易"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果学生向老师发送了一条消息,则该消息将保存在 teachers students 集合中.同样的情况是,当教师向学生发送消息时,他们也保存在两个集合中,分别是教师"和学生".我如何在以下代码中应用 mongoose transaction ,以便将消息保存在两个集合中.我不希望将消息保存在一个集合中,而将消息保存在另一个集合中由于错误而保存.我正在寻求帮助和线索

If the student sends a message to the teacher, the message is saved in the teachers and students collections. The same situation is when a teacher sends a message to the student, they are also save in the two collections teachers and 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. 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)
            }
}

记录的变量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:

等待session.abortTransaction();

await session.abortTransaction();

否则(幸福的道路)提交更改.

Otherwise (happy path) commit the changes.

等待session.commitTransaction();

await session.commitTransaction();

中止和提交是Promise的基础函数,因此我更改了用作异步的函数.

Abort and commit are Promise base functions, so I have changed the functions where they were used as async.

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();
}

这篇关于将消息保存在mongodb中的两个集合中时,使用“猫鼬交易"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆