Atomicity, isolation & concurrency in MongoDB

Most popular relational databases today support  “ACID” properties – Atomicity, Consistency, Isolation and Durability.  Developers and DBA’s working with relational databases have a good understanding of ACID behavior. However when working with NoSQL databases like MongoDB there are some key differences that are important to understand. MongoDB offers great flexibility in storage, schema and scaling, but relaxes some of the ACID properties. It is important you understand the differences as you model your data and execute mongodb commands.

Atomicity

Wikipedia defines “Atomicity”  as follows – “In an atomic transaction, a series of database operations either all occur, or nothing occurs. A guarantee of atomicity prevents updates to the database occurring only partially, which can cause greater problems than rejecting the whole series outright. In other words, atomicity means indivisibility and irreducibility”

MongoDB write operations are atomic only at the level of a single document. If you are modifying multiple subdocuments inside a document the operation is still atomic. If you are modifying multiple documents the operation is not atomic. So how do you achieve atomic behavior across multiple documents? You need to use a “Two phase commit” pattern to achieve the desired atomicity. Here is great example from the mongodb documentation on how to implement this pattern. The Two phase commit pattern is non trivial to implement and get right – so make sure multiple document write atomicity is something you want to shoot for.

Isolation

Wikipedia defines “Isolation” as follows –  “In database systems, isolation is a property that defines how/when the changes made by one operation become visible to other concurrent operations”.  There are multiple ways to achieve Isolation with your mongodb operations. Here are some

1. The “findAndModifyOperation()”  is one of the simplest ways to query and modify existing documents. The command can return either the previous values of the documents or the new updated values of the documents. You can also sort the matching documents, upsert and select which fields need to be returned.

db.collection.findAndModify( {
                               query: <document>,
                               sort: <document>,
                               remove: <boolean>,
                               update: <document>,
                               new: <boolean>,
                               fields: <document>,
                               upsert: <boolean>
                           } );

2. “Update if current” pattern – This patter is specified in the  mongodb documentation. It involves more manual work but gives you more control.

3. $isolation operator – The $isolation operator provides a way to isolate writes to multiple documents. How the $isolation operator does not provide all or nothing gaurantee – you will need to use some of the atomicity techniques specified in the first section to achieve that. Also the $isolation operator does not work for shards. This command used to be called “$atomic” – it has now been correctly renamed to “$isolated””.

Concurrency

MongoDB uses locks to prevent multiple clients from updating the same piece of data at the same time. MongoDB 2.2+ uses “database” level locks.So when one write operation locks the database all other write operations to the same database (even if they are to a separate collection) are blocked waiting on the lock. MongoDB uses  “writer greedy” locks – it favors writes over reads. In 2.2+ certain long running operations can yield their locks.

Thread safety

Not all of the MongoDB client classes are thread safe – please refer to the documentation of your specific driver to check if the classes you are using are thread safe. E.g. In the Java driver the MongoClient class is thread safe. So you can use a single instance of this class across all your threads. Internally MongoClient uses a connection pool to manage connections to the MongoDB server.

 As always if you have any questions please reach out to us at support@mongodirector.com.