1

I'm trying to test some update / delete scripts against a localhost MongoDB server (which is a docker instance).

eg.

update all users, set age = 50
delete all users where eyes = blue

select all users

If I was to do this with SQL, I would wrap the those three queries inside a TRANSACTION.

So I had a look online to doing transactions with MongoDB and it feels like it's a PITA -> I need a REPLICA SET, etc.

Is there a really easy way to:

  • create a mongodb instance with docker
  • write a script (like above) inside a transaction, and run this against that docker instance?

My reasoning for using a transaction is so i can change the data, get the current version of the data (after the change) .. eye ball the results ... and then roll back (revert) those changes. Then keep iterating through my script until I'm happy.

Here's some stuff I was trying to prove my point:

docker-compose.yml

version: '3.5'

services:

  mongodb.data:
    container_name: mongodb.data
    image: mongo
    ports:
      - 27017:27017 
    environment:
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=example
    volumes:
      - ./:/usr/src/mongo-data 

and some mongo shell script I'm playing around with in Studio 3T:



// Start a session.
session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );

// Start a transaction
session.startTransaction( { readConcern: { level: "local" }, writeConcern: { w: "majority" } } );

usersCollection = session.getDatabase("users").users;

usersCollection.find(
    { 
        "_id.userId" : "abcde1234"
    }
);


usersCollection.update(
    { "_id.userId" : "abcde1234" },
    {
        $set: {
            tags: Date()
        } 
    },
    { multi:true }
);


session.abortTransaction();
//session.commitTransaction();


session.endSession();

and the error I get when I try to use a transaction:

WriteCommandError({
    "ok" : 0,
    "errmsg" : "Transaction numbers are only allowed on a replica set member or mongos",
    "code" : 20,
    "codeName" : "IllegalOperation"
})

Is this even possible with a simple MongoDB setup?

Pure.Krome
  • 84,693
  • 113
  • 396
  • 647
  • You can have a replica set with 1 member. It won't be much different from a standalone from durability point of view but it will use opplog which is required for client sessions and transactions. – Alex Blex Mar 09 '21 at 11:22
  • So does this mean I need to change my docker-compose file to have some _extra_ argument that says: "yo mongodb .. start up with this port, blah blah .. AND .. be a replica set?" – Pure.Krome Mar 09 '21 at 12:55
  • yep. "be a replica set" syntax discussed in https://stackoverflow.com/questions/42190267/replica-set-mongo-docker-compose Adopt it to a single instance an you are good. – Alex Blex Mar 09 '21 at 13:03
  • the mongo docker image strips off --replSet argument when using authentication. you need to jump through hoops to setup a replicaset if using the official docker image. easiest thing is to just turn off authentication. then it works. [see here](https://github.com/dj-nitehawk/VisitorLog/tree/main/docker) for an example docker setup without auth. – Dĵ ΝιΓΞΗΛψΚ Mar 09 '21 at 15:01

0 Answers0