Search code examples
mongodbmongooseormnestjs

Transaction in mongo with Nestjs do not work


I want to make a transaction and I am using findOneAndUpdate I get the following error: "MongoServerError: Transaction numbers are only allowed on a replica set member or mongos". What I can do ?

app.module.ts:

imports...

@Module({
  imports: [
    ...,
    MongooseModule.forRoot(process.env.URL_DATABASE, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      retryAttempts: 2,
    }),
  ],
  controllers: [AppController],
  providers: [
    AppService,
  ],
})
export class AppModule {}

my.service.ts:

import { Connection } from "mongoose"

export class MyService {
 constructor(
    @InjectModel(User.name)
    private userModel: Model<UserDocument>,
    @InjectConnection() private readonly connection: Connection,
  ) {}
}

async delete(idPa: string): Promise<boolean> {
 let result = false;
 const session = await this.connection.startSession();

 try {
      await session.withTransaction(async () => {
        await this.userModel.findOneAndUpdate(
          { _id: idPa },
          { status: false },
          { session },
        );
      });

      result = true;
    } finally {
      await session.endSession();
    }
}

As a result when running my service from the controller I get: MongoServerError: Transaction numbers are only allowed on a replica set member or mongos.


Solution

  • I finally found the solution, it turns out that I must make an additional configuration to my database which is the "replica set".

    Follow these steps:

    1. Install mongosh
    2. Create 3 directories.
    3. Perform these commands:
    mongosh –-dbpath "C:\data1\db" –-port 27017 --replSet rs0 --bind_ip 127.0.0.1
    
    mongosh –-dbpath "C:\data2\db" –-port 27018 --replSet rs0 --bind_ip 127.0.0.1
    
    mongosh –-dbpath "C:\data3\db" –-port 27019 --replSet rs0 --bind_ip 127.0.0.1
    

    Note: For each of these commands open a new cmd

    1. Open a new cmd and open the parent directory: cmd mongosh --port 27017

    Once inside. Follow these steps.

    1. rs.initiate()
    2. rs.reconfig({ _id: "rs0", members: [{ _id: 0, host: "127.0.0.1:27017" }, { _id: 1, host: "127.0.0.1:27018" }, { _id: 2, host: "127.0.0.1:27019" }] }, {force:true});

    Then go to the child nodes, 27018 and 27019 and add the following commands.

    node 27018 go steps:

    1. mongosh --port 27018
    2. db.getMongo().setReadPref('secondary')

    node 27019 go steps:

    1. mongosh --port 27019
    2. db.getMongo().setReadPref('secondary')

    Finally, execute the transaction again, my app.module.ts remains exactly the same, remember that the local connection will always be 127.0.0.1