Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

410
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda