- MongoDB CRUD Operations >
- MongoDB CRUD Concepts >
- Read Isolation, Consistency, and Recency
Read Isolation, Consistency, and Recency¶
On this page
Isolation Guarantees¶
Read Uncommitted¶
In MongoDB, clients can see the results of writes before the writes are durable:
- Regardless of write concern, other
clients using
"local"
(i.e. the default) readConcern can see the result of a write operation before the write operation is acknowledged to the issuing client. - Clients using
"local"
(i.e. the default) readConcern can read data which may be subsequently rolled back.
Read uncommitted is the default isolation level and applies to
mongod
standalone instances as well as to replica sets and
sharded clusters.
Read Uncommitted And Single Document Atomicity¶
Write operations are atomic with respect to a single document; i.e. if a write is updating multiple fields in the document, a reader will never see the document with only some of the fields updated.
With a standalone mongod
instance, a set of read and write
operations to a single document is serializable. With a replica set,
a set of read and write operations to a single document is serializable
only in the absence of a rollback.
However, although the readers may not see a partially updated document, read uncommitted means that concurrent readers may still see the updated document before the changes are durable.
Read Uncommitted And Multiple Document Write¶
When a single write operation modifies multiple documents, the
modification of each document is atomic, but the operation as a whole
is not atomic and other operations may interleave. However, you can
isolate a single write operation that affects multiple documents
using the $isolated
operator.
Without isolating the multi-document write operations, MongoDB exhibits the following behavior:
- Non-point-in-time read operations. Suppose a read operation begins at time t1 and starts reading documents. A write operation then commits an update to one of the documents at some later time t2. The reader may see the updated version of the document, and therefore does not see a point-in-time snapshot of the data.
- Non-serializable operations. Suppose a read operation reads a document d1 at time t1 and a write operation updates d1 at some later time t3. This introduces a read-write dependency such that, if the operations were to be serialized, the read operation must precede the write operation. But also suppose that the write operation updates document d2 at time t2 and the read operation subsequently reads d2 at some later time t4. This introduces a write-read dependency which would instead require the read operation to come after the write operation in a serializable schedule. There is a dependency cycle which makes serializability impossible.
- Reads may miss matching documents that are updated during the course of the read operation.
Using the $isolated
operator, a write operation that affects
multiple documents can prevent other processes from interleaving once
the write operation modifies the first document. This ensures that no
client sees the changes until the write operation completes or errors
out.
$isolated
does not work with sharded clusters.
An isolated write operation does not provide “all-or-nothing” atomicity. That is, an error during the write operation does not roll back all its changes that preceded the error.
Note
$isolated
operator causes write operations to acquire
an exclusive lock on the collection, even for document-level
locking storage engines such as WiredTiger. That is,
$isolated
operator will make WiredTiger single-threaded
for the duration of the operation.
See also
Cursor Snapshot¶
MongoDB cursors can return the same document more than once in some situations. As a cursor returns documents other operations may interleave with the query. If some of these operations are updates that cause the document to move (in the case of MMAPv1, caused by document growth) or that change the indexed field on the index used by the query; then the cursor will return the same document more than once.
In very specific cases, you can isolate the cursor from returning
the same document more than once by using the
cursor.snapshot()
method. snapshot()
guarantees that the query will return each document no more than
once.
Warning
- The
snapshot()
does not guarantee that the data returned by the query will reflect a single moment in time nor does it provide isolation from insert or delete operations. - You cannot use
snapshot()
with sharded collections. - You cannot use
snapshot()
with thesort()
orhint()
cursor methods.
As an alternative, if your collection has a field or fields that are
never modified, you can use a unique index on this field or these
fields to achieve a similar result as the snapshot()
.
Query with hint()
to explicitly force the query to use
that index.
Monotonic Writes¶
MongoDB provides monotonic write guarantees for standalone
mongod
instances, replica sets, and sharded clusters.
Suppose an application performs a sequence of operations that consists of a write operation W1 followed later in the sequence by a write operation W2. MongoDB guarantees that W1 operation precedes W2.
Real Time Order¶
New in version 3.4.
For read and write operations on the primary, issuing read operations
with "linearizable"
read concern and write operations
with "majority"
write concern enables multiple threads
to perform reads and writes on a single document as if a single thread
performed these operations in real time; that is, the corresponding
schedule for these reads and writes is considered linearizable.