Search code examples
mongodbdatabase-administrationmongo-javareplicaset

How does Write Concern in MongoDB Work at Thread level?


As I see we can set write concern from the application, I was wondering how will MongoDB handle a scenario like this:

Lets say we have two task/Process (P1 and P2) running on same database (The database has a replica set of three nodes, 1 primary and 2 secondary). P1 has write concern enabled at journal level. P2 has write concern enabled at replica leve.(secondary level).

Now what will happen if P1 and P2 both writes to the database?

Will P2 wait for the data written by P1 to be copied to secondary and then write its data to secondary?

or how does it handle it?


Solution

  • Write concern is per operation and determines when MongoDB reports back to the client that the write was successful. It has nothing to do with other operations that are happening around the same time.

    If P1 has "write concern enabled at journal level", which I take to mean journaled write concern { "j" : 1 }, MongoDB won't report that operations sent by P1 are successful until they have been committed to the journal. Doesn't matter what the state of P2 writes are.

    If P2 has "write concern enabled at replica level", which I take to mean majority write concern { "w" : "majority" }, then every operation P2 does will not be reported as successful until it replicated to a majority of the nodes in the replica set. Doesn't matter what the state of P1 writes are.

    P1 and P2 operations will not wait for the other's write concern to be satisfied before they proceed, or anything like that.

    Edited response to comment into the answer since the response is long:

    Yes, the second write will have to wait for a database write lock to be released by the first write (possibly in the middle of a multi-document first write if the first write yields the lock), but the second write doesn't have to wait for the first write to fulfill its whole write concern.

    As an example, consider a write A with { "w" : "majority" } and a write B with { "w" : 1 }. A arrives first at the primary and takes the write lock. B arrives second and waits for the write lock. A finishes using the write lock and releases it; B takes the lock. A's write needs to be replicated to secondaries to fulfill its write concern - this is happening at the same time as B holds the write lock. B finishes and MongoDB responds to the client that the write was successful. A finishes replicating to the required number of replica set members and MongoDB responds that the write was a success. A was sent before B and wrote on the primary before B, during which time it held the lock and blocked B, but B returned first. It's not the write concern of A that holds up B, it's the simpler fact that MongoDB can't do two writes to the same database at once.