1

I'm trying to test the newly supported transactions in Mongo DB with a simple example I wrote. I'm using Mongo DB version 4.0.5 with driver version 2.8.1. It's only a primary instance with no shards/replicas.

I must be missing something basic in the following code. I create a Mongo client, session & database, then start a transaction, add a document and abort the transaction. After this code, I expect nothing to change in the database, but the document is added. When debugging I can also see the document right after the InsertOne() by using Robo 3T (Mongo client GUI).

Any idea what am I missing?

        var client =  new MongoClient("mongodb://localhost:27017");
        var session = client.StartSession();
        var database = session.Client.GetDatabase("myDatabase", new MongoDatabaseSettings
        {
            GuidRepresentation = GuidRepresentation.Standard,
            ReadPreference = ReadPreference.Primary,
            WriteConcern = new WriteConcern(1, 
                new MongoDB.Driver.Optional<TimeSpan?>(TimeSpan.FromSeconds(30))),

        });

        var entities = database.GetCollection<MyEntity>("test");            

        session.StartTransaction();

        // After this line I can already see the document in the db collection using Mongo client GUI (Robo 3T), although I expect not to see it until committing
        entities.InsertOne(new MyEntity { Name =  "Entity" });

        // This does not have any effect
        session.AbortTransaction();

Edit:

It's possible to run MongoDB as a 1-node replica set, although I'm not sure what's the difference between a standalone and a 1-node replica set. See my post below.

In any case, to use the started transaction the insertion code must receive the session as a parameter:

entities.InsertOne(session, new MyEntity { Name = "Entity" });

With these 2 change now the transaction works.

Metheny
  • 1,112
  • 1
  • 11
  • 23
  • A bit of shameless advertising: If you don't feel like passing around the session object everywhere, JohnKnoop.MongoRepository provides an abstraction that automatically enlists with the current transaction: https://github.com/johnknoop/MongoRepository#transactions – John Knoop Aug 07 '20 at 13:14

2 Answers2

3

This is inherently a property of MongoDB itself. (More here and here)

Transactions are only available in a replica set setup

Why isnt it available for standalone instances?

With subdocuments and arrays, document databases (MongoDB) allow related data to be unified hierarchically inside a single data structure. The document can be updated with an atomic operation, giving it the same data integrity guarantees as a multi-table transaction in a relational database.

  • Wow, that's really over simplified reasoning. It seems they are practically saying that the design is forced to contain a single collection in order to use transactions, or rather transaction-like behavior. Obviously this constraint doesn't fit many applications, including mine. – Metheny May 27 '19 at 13:41
  • The answer here is incorrect. There is no relation between MongoDB topology and data modelling (one collection or multi collections). The transaction is not available in standalone because it requires `oplog` to maintain strong consistency within a cluster. Technically you can run a standalone MongoDB with oplog (replica set with one node), although this is not recommended for production as you don't have redundancy. I would suggest to watch the engineering videos on https://www.mongodb.com/transactions to understand the behind-the-scene. – Wan B. Jul 11 '19 at 03:53
2

I found a solution, although not sure what the consequences are, maybe someone can point it out: It seems it's possible to use Mongo DB as a 1-node replica set (instead of a standalone) by simply adding the following in the mongod.cfg file:

replication:
   replSetName: rs1

Also, thanks to the following link the code should use the correct overload of InsertOne() which receives the session as the first parameter (see the edit on the original post):

multiple document transaction not working in c# using mongodb 4.08 community server

Metheny
  • 1,112
  • 1
  • 11
  • 23