With MongoDB’s causally consistent client sessions, different combinations of read and write concerns provide different causal consistency guarantees. When causal consistency is defined to imply durability, then the following table lists the specific guarantees provided by the various combinations:
| Read Concern | Write Concern | Read own writes | Monotonic reads | Monotonic writes | Writes follow reads |
|---|---|---|---|---|---|
"majority" |
"majority" |
✅ | ✅ | ✅ | ✅ |
"majority" |
{ w: 1 } |
✅ | ✅ | ||
"local" |
{ w: 1 } |
||||
"local" |
"majority" |
✅ |
If causal consistency implies durability, then, as seen from the table, only read operations with "majority" read concern and write operations with "majority" write concern can guarantee all four causal consistency guarantees. That is, causally consistent client sessions can only guarantee causal consistency for:
"majority" read concern; i.e. the read operations that return data that has been acknowledged by a majority of the replica set members and is durable."majority" write concern; i.e. the write operations that request acknowledgement that the operation has been applied to a majority of the replica set’s voting members.If causal consistency does not imply durability (i.e. writes may be rolled back), then write operations with { w: 1 } write concern can also provide causal consistency.
Note
The other combinations of read and write concerns may also satisfy all four causal consistency guarantees in some situations, but not necessarily in all situations.
The read concern "majority" and write concern "majority" ensure that the four causal consistency guarantees hold even in circumstances (such as with a network partition) where two members in a replica set transiently believe that they are the primary. And while both primaries can complete writes with { w: 1 } write concern, only one primary will be able to complete writes with "majority" write concern.
For example, consider a situation where a network partition divides a five member replica set:
With the above partition
"majority" write concern can complete on Pnew but cannot complete on Pold.{ w: 1 } write concern can complete on either Pold or Pnew. However, the writes to Pold (as well as the writes replicated to S1) roll back once these members regain communication with the rest of the replica set."majority" write concern on Pnew, causally consistent reads with "majority" read concern can observe the write on Pnew, S2,and S3. The reads can also observe the write on Pold and S1 once they can communicate with the rest of the replica set and sync from the other members of the replica set. Any writes made to Pold and/or replicated to S1
during the partition are rolled back.To illustrate the read and write concern requirements, the following scenarios have a client issue a sequence of operations with various combination of read and write concerns to the replica set:
"majority" and Write concern "majority"¶The use of read concern "majority" and write concern "majority" in a causally consistent session provides the following causal consistency guarantees:
✅ Read own writes ✅ Monotonic reads ✅ Monotonic writes ✅ Writes follow reads
Scenario 1 (Read Concern “majority” and Write Concern “majority”)
During the transient period with two primaries, because only Pnew can fulfill writes with { w: "majority" } write concern, a client session can issue the following sequence of operations successfully:
| Sequence | |
|---|---|
1. Write1 with write concern
"majority" to Pnew2. Read1 with read concern
"majority" to S23. Write2 with write concern
"majority" to Pnew4. Read2 with read concern "majority" to S3 |
For item
A, update qty to 50.Read item
A.For items with
qty less than or equal to 50,update
restock to true.Read item A. |
| ✅ Read own writes | Read1 reads data from
S2 that reflects a state after Write1.Read2 reads data from S1 that reflects a state after Write11 followed by Write2. |
| ✅ Monotonic reads | Read2 reads data from S3 that reflects a state after Read1. |
| ✅ Monotonic writes | Write2 updates data on Pnew that reflects a state after Write1. |
| ✅ Writes follow reads | Write2 updates data on Pnew that reflects a state of the data after Read1 (i.e. an earlier state reflects the data read by Read1). |
Scenario 2 (Read Concern “majority” and Write Concern “majority”)
Consider an alternative sequence where Read1 with read concern "majority" routes to S1:
| Sequence | |
|---|---|
1. Write1 with write concern
"majority" to Pnew2. Read1 with read concern
"majority" to S13. Write2 with write concern
"majority" to Pnew4. Read2 with with read concern "majority" to S3 |
For item
A, update qty to 50.Read item
A.For items with
qty less than or equal to 50,update
restock to true.Read item A. |
In this sequence, Read1 cannot return until the majority commit point has advanced on Pold. This cannot occur until Pold and S1 can communicate with the rest of the replica set; at which time, Pold
has stepped down (if not already), and the two members sync (including Write1) from the other members of the replica set.
| ✅ Read own writes | Read1 reflects a state of data after Write11, albeit after the network partition has healed and the member has sync’ed from the other members of the replica set. Read2 reads data from S3 that reflects a state after Write11 followed by Write2. |
| ✅ Monotonic reads | Read2 reads data from S3 that reflects a state after Read1 (i.e. an earlier state is reflected in the data read by Read1). |
| ✅ Monotonic writes | Write2 updates data on Pnew that reflects a state after Write1. |
| ✅ Writes follow reads | Write2 updates data on Pnew that reflects a state of the data after Read1 (i.e. an earlier state reflects the data read by Read1). |
"majority" and Write concern {w: 1}¶The use of read concern "majority" and write concern { w: 1 } in a causally consistent session provides the following causal consistency guarantees if causal consistency implies durability:
❌ Read own writes ✅ Monotonic reads ❌ Monotonic writes ✅ Writes follow reads
If causal consistency does not imply durability:
✅ Read own writes ✅ Monotonic reads ✅ Monotonic writes ✅ Writes follow reads
Scenario 3 (Read Concern “majority” and Write Concern {w: 1})
During the transient period with two primaries, because both Pold and Pnew can fulfill writes with { w: 1 } write concern, a client session could issue the following sequence of operations successfully but not be causally consistent if causal consistency implies durability:
| Sequence | |
|---|---|
1. Write1 with write concern
{ w: 1 } to Pold2. Read1 with read concern
"majority" to S23. Write2 with write concern
{ w: 1 } to Pnew4. Read2 with with read concern "majority" to S3 |
For item
A, update qty to 50.Read item
A.For items with
qty less than or equal to 50,update
restock to true.Read item A. |
In this sequence,
Pnew past the time of Write1.Pnew past the time of Write2.➤ If causal consistency implies durability
| ❌ Read own writes | Read1 reads data from S2 that does not reflect a state after Write1. |
| ✅ Monotonic reads | Read2 reads data from S3 that reflects a state after Read1 (i.e. an earlier state is reflected in the data read by Read1). |
| ❌ Monotonic writes | Write2 updates data on Pnew that does not reflect a state after Write1. |
| ✅ Writes follow reads | Write2 updates data on Pnew that reflects a state after Read1 (i.e. an earlier state reflects the data read by Read1). |
➤ If causal consistency does not imply durability
| ✅ Read own writes | Read1 reads data from S2 returns data that reflects a state equivalent to Write1 followed by rollback of Write1. |
| ✅ Monotonic reads | Read2 reads data from S3 that reflects a state after Read1 (i.e. an earlier state is reflected in the data read by Read1). |
| ✅ Monotonic writes | Write2 updates data on Pnew that is equivalent to after Write1 followed by rollback of Write1. |
| ✅ Writes follow reads | Write2 updates data on Pnew that reflects a state after Read1 (i.e. whose earlier state reflects the data read by Read1). |
Scenario 4 (Read Concern “majority” and Write Concern {w: 1})
Consider an alternative sequence where Read1 with read concern "majority" routes to S1:
| Sequence | |
|---|---|
1. Write1 with write concern
{ w: 1 } to Pold2. Read1 with read concern
"majority" to S13. Write2 with write concern
{ w: 1 } to Pnew4. Read2 with with read concern "majority" to S3 |
For item
A, update qty to 50.Read item
A.For items with
qty less than or equal to 50,update
restock to true.Read item A. |
In this sequence:
S1. This cannot occur until Pold and S1 can communicate with the rest of the replica set. At which time, Pold has stepped down (if not already), Write1 is rolled back from Pold and S1, and the two members sync from the other members of the replica set.➤ If causal consistency implies durability
| ❌ Read own writes | The data read by Read1 does not reflect the results of Write1, which has rolled back. |
| ✅ Monotonic reads | Read2 reads data from S3 that reflects a state after Read1 (i.e. whose earlier state reflects the data read by Read1). |
| ❌ Monotonic writes | Write2 updates data on Pnew that does not reflect a state after Write1, which had preceded Write2 but has rolled back. |
| ✅ Writes follow reads | Write2 updates data on Pnew that reflects a state after Read1 (i.e. whose earlier state reflects the data read by Read1). |
➤ If causal consistency does not imply durability
| ✅ Read own writes | Read1 returns data that reflects the final result of Write1 since Write1 ultimately rolls back. |
| ✅ Monotonic reads | Read2 reads data from S3 that reflects a state after Read1 (i.e. an earlier state reflects the data read by Read1). |
| ✅ Monotonic writes | Write2 updates data on Pnew that is equivalent to after Write1 followed by rollback of Write1. |
| ✅ Writes follow reads | Write2 updates data on Pnew that reflects a state after Read1 (i.e. an earlier state reflects the data read by Read1). |
"local" and Write concern {w: 1}¶The use of read concern "local" and write concern { w: 1 } in a causally consistent session cannot guarantee causal consistency.
❌ Read own writes ❌ Monotonic reads ❌ Monotonic writes ❌ Writes follow reads
This combination may satisfy all four causal consistency guarantees in some situations, but not necessarily in all situations.
Scenario 5 (Read Concern “local” and Write Concern {w: 1})
During this transient period, because both Pold and Pnew can fulfill writes with { w: 1 } write concern, a client session could issue the following sequence of operations successfully but not be causally consistent:
| Sequence | |
|---|---|
For item
A, update qty to 50.Read item
A.For items with
qty less than or equal to 50,update
restock to true.Read item A. |
| ❌ Read own writes | Read2 reads data from S3 that only reflects a state after Write2 and not Write1
followed by Write2. |
| ❌ Monotonic reads | Read2 reads data from S3 that does not reflect a state after Read1 (i.e. an earlier state does not reflect the data read by Read1). |
| ❌ Monotonic writes | Write2 updates data on Pnew that does not reflect a state after Write1. |
| ❌ Write follow read | Write2 updates data on Pnew that does not reflect a state after Read1 (i.e. an earlier state does not reflect the data read by Read1). |
"local" and Write concern "majority"¶The use of read concern "local" and write concern "majority" in a causally consistent session provides the following causal consistency guarantees:
❌ Read own writes ❌ Monotonic reads ✅ Monotonic writes ❌ Writes follow reads
This combination may satisfy all four causal consistency guarantees in some situations, but not necessarily in all situations.
Scenario 6 (Read Concern “local” and Write Concern “majority”)
During this transient period, because only Pnew can fulfill writes with { w: "majority" } write concern, a client session could issue the following sequence of operations successfully but not be causally consistent:
| Sequence | |
|---|---|
1. Write1 with write concern
"majority" to Pnew2. Read1 with read concern
"local" to S13. Write2 with write concern
"majority" to Pnew4. Read2 with read concern "local" to S3 |
For item
A, update qty to 50.Read item
A.For items with
qty less than or equal to 50,update
restock to true.Read item A. |
| ❌ Read own writes. | Read1 reads data from S1 that does not reflect a state after Write11. |
| ❌ Monotonic reads. | Read2 reads data from S3 that does not reflect a state after Read1 (i.e. an earlier state does not reflect the data read by Read1). |
| ✅ Monotonic writes | Write2 updates data on Pnew that reflects a state after Write1. |
| ❌ Write follow read. | Write2 updates data on Pnew that does not reflect a state after Read1 (i.e. an earlier state does not reflect the data read by Read1). |