MongoDB Transactions: Your Very First Transaction with MongoDB 4.0

MongoDB 4.0MongoDB 4.0 transactions is just around the corner and with rc0 we can get a good idea of what we can expect in the GA version. MongoDB 4.0 will allow transactions to run in a replica set and, in a future release, the MongoDB transaction will work for sharded clusters. This is a really big change!

Multi-statement transactions are a big deal for a lot of companies. The transactions feature has been in development since MongoDB version 3.0; in version 3.6 logical sessions were added. In an earlier blog post we highlighted a few details from what was delivered in 3.6 that indicated that 4.0 would have transactions.

There are a few limitations for transactions and some operations are not allowed yet. A detailed list can be found in the MongoDB documentation of the Session.startTransaction() method.

One restriction that we must be aware of is that the collection MUST exist in order to use transactions.

A simple transaction will be declared in a very similar way to that we use for other databases. The caveat is that we need to start a session before starting a transaction. This means that multi-statement transactions are not the default behavior to write to the database.

How to use transactions in MongoDB® 4.0

Download MongoDB 4.0 RC (or you can install it from the repositories).

Uncompress the files:

Rename the folder to mongo4.0 and create the data folder inside of the bin folder:

Start the database process:
Important: in order to have multi-statement transactions replica-set must be enabled

Initialize the replica-set:

Start a session and then a transaction:

Then you can decide whether to commit the transaction or abort it:

If the startTransaction throws the IllegalOperation error, make sure the database is running with replica set.

Transaction isolation level in in MongoDB 4.0: Snapshot Isolation

MongoDB 4.0 implements snapshot isolation for the transactions. The pending uncommitted changes are only visible inside the session context (the session which has started the transaction) and are not visible outside. Here is an example:

Connection 1:

Connection 2: starting second transaction in its own session:

Connection 1: commit

Connection 2: after connection1 commits:

Outside of the session it sees the new values, however inside the opened session it will not see the new values.

Now if we commit the transaction inside connection 2 it will commit as well, and we will have 2 rows now (as there are no conflicts).

Sometimes, however, we may see the transient transaction error when committing or even doing find() inside a session:

From the MongoDB doc we can read that we could retry the transaction back when we have this error.

If an operation encounters an error, the returned error may have an errorLabels array field. If the error is a transient error, the errorLabels array field contains “TransientTransactionError” as an element and the transaction as a whole can be retried.

MongoDB transactions: conflict

What about transaction conflicts in MongoDB? Let’s say we are updating the same row. Here is the demo:

First we create a record, trx, in the collection:

Then we create session1 and update trx to change from 0 to 1:

Then (before committing) create another session which will try to change from 0 to 2:

As we can see, MongoDB catches the conflict and return the error on the insert (even before the commit).

We hope this post, with its simple example how transactions will work, has been useful. Feedback is welcome: you can comment here, catch Adamo on twitter @AdamoTonete or talk to the team at @percona.

You May Also Like

For more information on how multi-document ACID transactions are supported in MongoDB 4.0, watch our webinar, MongoDB 4.0 Features – Transactions & More. Other topics and features covered include future transaction improvements, non-blocking secondary reads and security improvements. We know data integrity is crucial for your business. Our blog, MongoDB: how to use the JSON Schema Validator, explains how to introduce schema validation checks at the database level to enforce the integrity of your data.

Share this post

Comments (3)

  • Mark Callaghan

    Does snapshot isolation mean this is similar to repeatable read in Postgres and MyRocks?

    Gap locks as used by InnoDB can be confusing, but make RR more useful. For linkbench I need to use RC with MyRocks, while RR works fine with InnoDB (thanks to gap locks). I have yet to run it for Postgres, but assume that would have to use RC as well (because PG RR doesn’t do gap locks).

    June 27, 2018 at 9:45 am
  • rehu

    This article is very nice. I implemented multi-document transaction. Thanks for your help. But I’ve a tweaked requirement from my client. In this article, at the end you are updating same document from 2 sessions. While first one has updated the document but not committed, in the meanwhile one more session has already accessed it and while updating its getting “writeConflict” error. Seems ok from our end but the client wants that the 2nd session should not be able to pull the same document which is already in the previous session. We dont want all the codes and at last facing writeConflict error. We should get the error on prior pulling the document. Any help would be appreciated.

    September 14, 2018 at 5:57 am
  • Anand Gupta

    Does mysql support snapshot isolation??

    November 15, 2018 at 12:52 pm

Comments are closed.

Use Percona's Technical Forum to ask any follow-up questions on this blog topic.