Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

409
Views
mongoose doesn't abort the transaction when promise.all rejects

i'm trying to save several documents in a transaction and if i'm using Promise.all to run operations in parallel, and one of them fails and the promise rejects, then the other operations should rollback, but it doesn't happen if running operations one by one, then it's working as expected

so here's the working script:

import mongoose from "mongoose";

main()
  .then(() => console.log('done'))
  .catch(err => console.log(err));

const userSchema = new mongoose.Schema({
  email: {
    type: String,
    required: true,
  },
  password: {
    type: String,
  },
});

const User = mongoose.model('User', userSchema);

async function main() {
  await mongoose.connect('mongodb://127.0.0.1:27017/transaction-test?replicaSet=myReplicaSet');

  const users = [
    {
      email: 'cred@mail.ru',
      password: '123',
    },
    {
      email: 'buba@mail.ru',
      password: '123',
    },
    {
      password: '1234',  // no 'email' property so trying to save it will result in validation error
    },
  ];

  await User.db.transaction(async session => {
    const promise1 = User.create([users[0]], { session });
    const promise2 = User.create([users[1]], { session });
    const promise3 = User.create([users[2]], { session });
    await promise1;
    await promise2;
    await promise3;
  });
};

the above code will work as intended and no docs will end up getting saved in the db, but if i replace the transaction part with:

  await User.db.transaction(async session => {
    const promise1 = User.create([users[0]], { session });
    const promise2 = User.create([users[1]], { session });
    const promise3 = User.create([users[2]], { session });
    await Promise.all([promise1, promise2, promise3]);
  });
};

then the first two docs will not rollback and will actually get saved to the db although the function will throw a validation error

mongoose version is 6.1.7 mongod version v5.0.4

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Try with startTransaction and commitTransaction. Something like this:

const session = await mongoose.startSession();
session.startTransaction();

try {

  const promise1 = User.create([users[0]], { session });
  const promise2 = User.create([users[1]], { session });
  const promise3 = User.create([users[2]], { session });
  await Promise.all([promise1, promise2, promise3]);

  await session.commitTransaction();

} catch(error){
  // Rollback any changes made in the database
  await session.abortTransaction();

  // logging the error
  console.error(error);

  // Rethrow the error
  throw error;
} finally {
  // Ending the session
  session.endSession();
}
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!