Home > Net >  Mongoose - session abortTransaction is not rolling back
Mongoose - session abortTransaction is not rolling back

Time:06-13

I don't know what I'm missing but in the block catch session.abortTransaction() not rolling bak anything. I purposely used throw new Error("Error message") after the creation of a user to land in the catch block to trigger the session.abortTransaction() but when I look in the database I see that the user is still created despite the abortion.

Here is my source code

export const signUp = async (req, res) => {
    const { email, password, fullname } = req.body;
    // Init session
    const session = await mongoose.startSession(); 
    // Begin transaction
    session.startTransaction(); 
    try {
        // Check if user exist in database using his email
        const dbUser = await UserModel.findOne({ email }, null, session);

        // Return a conflit code if user already exist
        if (dbUser) return res.status(409).json({ message: "User already exists" });
        
        // Create tenant
        const tenantResult = await TenantModel.create([{ createdAt: new Date() }], null, session);

        // Get admin role
        const roleResult = await RoleModel.findById('626db17b8645717d657fc4c8', null, session);

        //Hash password using jwt
        const hashedPassword = await bcrypt.hash(password, 12);

        
        // Store user in db
        const userResult = await UserModel.create([
            { 
                email: email, 
                password: hashedPassword, 
                fullname: fullname, 
                tenant: tenantResult[0], 
                role: roleResult 
            }
        ], null, session);
        throw new Error("Error message");

        if (userResult){
            // Create subscription && currency
            
            // Create currency for user
            await CurrencyModel.create([
                {
                    name: 'Dollar', 
                    createdAt: new Date(),
                    symbol: '$', 
                    isoCode: 'USD', 
                    default: true,
                    userRole: 'setting-list',
                    createdBy: userResult[0],
                }
            ], null, session);
        }

        // Generate token using jwt, secret, and user data
        const token = jwt.sign( { email: userResult[0].email, id: userResult[0]._id }, secret, { expiresIn: "24h" } );

        // Send welcome email to registered user
        await sendWelcomeEmail(userResult[0].email, userResult[0].fullname, `Welcome ${userResult[0].fullname} - light-speed.dev`, 'welcome-email.html');
        
        //Commit transaction
        await session.commitTransaction();

        // Return 201 Created http code with user and token
        return res.status(201).json({ userResult, token });
    } catch (error) {
        // Abort transaction if one of these request throw error
        await session.abortTransaction();
        console.log(error);
        return res.status(400).json({ message: 'Something went wrong!' });

    } finally {
        // close session
        session.endSession();

    }
};

Thank you for your help!

CodePudding user response:

I finally figured out why the session doesn't roll back transactions. It's because of the way I specify the session option.

I change these lines

const dbUser = await UserModel.findOne({ email }).session(session);

const tenantResult = await TenantModel.create([{ createdAt: new Date() }], { session: session });

const roleResult = await RoleModel.findById('626db17b8645717d657fc4c8').session(session);


const userResult = await UserModel.create([
        { 
            email: email, 
            password: hashedPassword, 
            fullname: fullname, 
            tenant: tenantResult[0], 
            role: roleResult 
        }
    ], { session: session });


await CurrencyModel.create([
            {
                name: 'Dollar', 
                createdAt: new Date(),
                symbol: '$', 
                isoCode: 'USD', 
                default: true,
                userRole: 'setting-list',
                createdBy: userResult[0],
            }
        ], { session: session });
  • Related