MongoDB transactions don't seem to be working

I have to update two collections. I want to make sure that either both the collections get updated or they don’t.

I created this simple example of two updates (both of them use same collection here, but they could be different):

  await this.client.connect();
    const session = this.client.startSession();

    try{
      
    await session.withTransaction(async () => {
    await this.client.db("Person").collection("persons").updateMany({ "phone":  "23138213"}, {$set: {"gender": "Male"} }, function(err, res) {
      if (err) throw err;
      console.log(res.result.nModified + " document(s) updated");
    });

    await this.client.db("Person").collection("persons").updateMany({ "phone":  "23138213"},  "Other"  , function(err, res) {
      if (err) throw err;
      console.log(res.result.nModified + " document(s) updated");
    });

  })
}
  finally{
    await session.endSession();

  }

Now if the initial value of gender was empty "". Then after executing the above code, the final value should still be "" because the second update is invalid syntax and would throw exception.

But the result is gender:Male

Hi @jim_rock,

There are a few things here. You need to pass the session into the operation as a transaction options. Otherwise the operation will be performed outside of a session. For example:

await this.client.db("Person").collection("persons").updateMany({ "phone":  "23138213"}, {$set: {"gender": "Male"} },  {"session":session},  
     function(err, res) {
         if (err) throw err;
             console.log(res.result.nModified + " document(s) updated");
     }
);

See also Collection.updateMany() for more information on transaction options.

In addition, the update operation is structured with callbacks. In this case, what likely to happen is the first update was executed then the second thrown an exception.
If you’re using async functions, you could use await operator with a Promise to pause further execution until the Promise is resolved. You can do sequential logic execution in this manner, for example:

let result1 = await client.db("nodejs").collection("one").updateMany({ "phone":  "123"}, {"$set": {"gender": "Male"} }, {"session": session});
let result2 = await client.db("nodejs").collection("two").updateMany({ "phone":  "123"},  {"$set":{"name":"foobar"}} , {"session": session});

Alternatively if you would like to use callbacks, you should nest them. Please see Promises and Callbacks for more information.

If you would like to abort a transaction, you should explicitly call ClientSession.abortTransaction(). i.e. if error then abort. For more information, see also QuickStart Node.JS: How To Implement Transactions.

Regards,
Wan.