estoy tratando de guardar varios documentos en una transacción y si estoy usando Promise.all para ejecutar operaciones en paralelo, y uno de ellos falla y la promesa se rechaza, entonces las otras operaciones deberían revertirse, pero no sucede si ejecutando operaciones una por una, entonces funciona como se esperaba
así que aquí está el guión de trabajo:
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; }); };el código anterior funcionará según lo previsto y no se guardará ningún documento en la base de datos, pero si reemplazo la parte de la transacción con:
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]); }); };entonces los dos primeros documentos no se revertirán y en realidad se guardarán en la base de datos aunque la función arrojará un error de validación
mangosta versión es 6.1.7 mongod versión v5.0.4
Prueba con startTransaction y commitTransaction . Algo como esto:
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(); }