简体   繁体   中英

mongoose how to send transaction multiple collections

Side-Note I connect to DB with the following code:

const mongoose = require('mongoose');

const connectDB = (url) => {
  return mongoose.connect(url);
}

Problem Description: I have two different Collections. Both Operations, findByIdAndUpdate and create must run as an atomic operation. This should be possible with mongoose Transactions.

const registerCustomer = async (req, res) => {
   await CustomerRegistrationCode.findByIdAndUpdate(req.body._id, { used: true });
   const customer = await Customer.create({firstName: req.body.firstName});
}

What I tried:

const registerCustomer = async (req, res) => {
    const session = await mongoose.startSession();
    await session.startTransaction();
    try {
        await CustomerRegistrationCode.findByIdAndUpdate(req.body._id, { used: true }); //updates even though 
        const customer = await Customer.create({ firstName: req.body.firstName });// this line will throw error
        await session.commitTransaction();
        session.endSession();
    } catch (error) {
        console.error('abort transaction');
        await session.abortTransaction();
        session.endSession();
        throw error;
    }
}

Problem The CustomerRegistrationCode Collection gets updated even though the Customer.create method throws an error. How can this be solved?

You are using the transaction in a wrong way, that is why it does not work.

You need to pass the session object to your operations.

const registerCustomer = async (req, res) => {
    const session = await mongoose.startSession();
    session.startTransaction();
    try {
        await CustomerRegistrationCode.findByIdAndUpdate(req.body._id, { used: true }, { session });
        const customer = await Customer.create({ firstName: req.body.firstName }, { session });
        await session.commitTransaction();
    } catch (error) {
        console.error('abort transaction');
        await session.abortTransaction();
    } finally {
        session.endSession();
    }
}

Also, I have refactored your code a bit.

You can read more about transactions here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM