mongodbmongoosetransactions

Mongoose transaction session.withTransaction is not a function


I was reading these links trying to implement mongoose transactions: Mongoose pass data out of withTransaction helper https://github.com/mongodb-developer/nodejs-quickstart/blob/master/transaction.js

I want to code a working sample by updating a client then implement the rollback on failed. But I got stuck with these two errors: The transaction was aborted due to an unexpected error: TypeError: session.withTransaction is not a function (node:60708) UnhandledPromiseRejectionWarning: TypeError: session.endSession is not a function

replica set is set up: run-rs -v 4.0.0 --shell

Purging database...
Running '/usr/local/lib/node_modules/run-rs/4.0.0/mongod' [ 27017, 27018, 27019 ]
Starting replica set...
(node:61139) Warning: Accessing non-existent property 'count' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
(node:61139) Warning: Accessing non-existent property 'findOne' of module exports inside circular dependency
(node:61139) Warning: Accessing non-existent property 'remove' of module exports inside circular dependency
(node:61139) Warning: Accessing non-existent property 'updateOne' of module exports inside circular dependency
Started replica set on "mongodb://localhost:27017,localhost:27018,localhost:27019?replicaSet=rs"
Running mongo shell: /usr/local/lib/node_modules/run-rs/4.0.0/mongo

the code:

ADMIN_MONGO_URL: "mongodb://localhost:27017/admin?retryWrites=true&w=majority",
       
transactionCreateProject: async function (newProjectJson) {
            const mongoConnectConfig = {useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true};
            const connection = await mongoose.connect(CONSTANTS.ADMIN_MONGO_URL, mongoConnectConfig)
            const db = mongoose.connection;
            db.on('error', console.error.bind(console, 'MongoDB connection error:'))
            let projectModel = mongoose.model('project', mongooseProjectSchema)
    
            // either of next two line does not work.
            const session = connection.startSession();
            // const session = mongoose.startSession();
    
            const transactionOptions = {
                readPreference: 'primary',
                readConcern: { level: 'local' },
                writeConcern: { w: 'majority' }
            };
            try {
                const transactionResults = await session.withTransaction(async () => {
                    let resultObj = await projectModel.updateOne({'uuid': newProjectJson['clientID']}, {$push: {'accumulatedProj': {'uuid': newProjectJson.uuid}}});
                    console.log(resultObj)
                }, transactionOptions);
                console.log(transactionResults)
                if (transactionResults) {
                    console.log("The reservation was successfully created.");
                } else {
                    console.log("The transaction was intentionally aborted.");
                }
            }
            catch (e) {
                console.log("The transaction was aborted due to an unexpected error: " + e);
            }
            finally {
                await session.endSession();
            }

What did I do wrong?


Solution

  • You need to put an await when declaring session like this:

    const session = await connection.startSession()
    

    if you log session without the await you can see that it is a promise, so basically you just need to put the await and you're good