How can I implement transaction concept in mongoose model?

Viewed 570

I have three models "userLogin.js","userDetail.js",and "userAddress.js".I want data should be stored simultaneously, if any error occurs it should rolback all the insert actions.this what I have tried. I gives me the error user is not defined . when try to fix them it gives the error "schema is not registered"

 const UserLogin=require("../models/userLogin");
 const UserDeatil=require("../models/userDetail");

 var myModelSchema1 = require('mongoose').model('UserLogin').schema;
 var myModelSchema2 = require('mongoose').model('UserDeatils').schema;

 exports.user_signup = (req, res, next) => {
 UserLogin.find({ email: req.body.email })
.exec()
.then(user => {
  if (user.length >= 1) {
    return res.status(409).json({
      message: "Mail exists"
    });
  } else {
    bcrypt.hash(req.body.password, 10, (err, hash) => {
      if (err) {
        return res.status(500).json({
          error: err
        });
      } else {
        const user = new UserLogin({
          _id: new mongoose.Types.ObjectId(),

          email: req.body.email,
          password: hash,
          loginDate:req.body.logindate,

        });
   const userdetils = new UserDeatil({
                  _id: new mongoose.Types.ObjectId(),
                  userId:result.userID,
                  userName:req.body.username,
                  dob:req.body.dob,
                  gender:req.body.gender,
                  photo: req.file? req.file.path : null,
                  imei:req.body.imei,

                });
         insertUsers();



        }
       });
       }
       });
       };

        async function insertUsers(){
          try{

            const id= transaction.insert(myModelSchema1, user);
            const id1= transaction.insert(myModelSchema2, userdetils);
            const final = await transaction.run();

          }
          catch(error){

            console.error(error);
            const rollbackObj = await transaction.rollback().catch(console.error);
            transaction.clean();
            c
          }

        }
2 Answers

first when you define your users schema the email must be uniqe wich when fails when you tries to create anothe user document with the same email,

and with this convention you can move forward like this:

 const UserLogin=require("../models/userLogin");
 const UserDeatil=require("../models/userDetail");

 cosnt signup = async (req ,res)=>{
   const { email , password ,...details} = req.body
   const createdDocs = []
   const hashedPwd = hash(password);

   try{
      const user = new UserLogin({ email , password: hashedPwd });

      await user.save()

      createdDocs.push(user)


      const userDetails = new UserDetails({...details,userId:user._id});

      await userDetails.save()


      createdDocs.push(userDetails)

 catch(err){

  res.json({ status:false, message:err.message})

  //emulates the rollback when any thing fails on the try flow 
  if(createdDocs.length){
   const operationsToRollBack = createdDocs.map(doc=>doc.remove)
   await Promise.all(operationsToRollBack)
  }

}

MongoDB supports multi-document transactions starting from version 4.0.

Ideally, if you need a transactional database you would use an SQL type db. But if you would still like to enjoy MongoDB while needing transactions, they have introduced an API for this - https://docs.mongodb.com/manual/core/transactions/

Related