- Does MongoDB block the read requests of those 3 clients until the 2 clients finish updating data?
No, MongoDB does not block read requests while write operations are in progress. MongoDB uses multi-version concurrency control (MVCC) system, which allows reads and writes to occur concurrently in most cases. Here’s how it basically works:
- For read operations, MongoDB provides a view of the data at the time the read operation begins… even if a write operation is in progress, read operations will see the data as it was before the write started.
- Write operations acquire locks to ensure data consistency, but these locks don’t block read operations, afaik.
- Do I need a certain locking mechanism to preserve data consistency for multiple read and write parallel requests?
In most cases, you don’t need to implement additional locking mechanisms yourself. MongoDB’s built-in concurrency control is designed to handle multiple concurrent read and write operations. A few things to keep in mind tho…
a) Write Concerns: Ensure you’re using appropriate write concerns for your update operations. This helps ensure that writes are properly propagated before subsequent reads.
b) Read Concerns: If you need the most up-to-date data in your read operations, you might want to use a higher read concern level, such as “majority”.
c) Atomic Operations: For updating the availableQuota and usedInstallmentIds, consider using atomic update operations to ensure consistency. For example:
db.installmentPromos.updateOne(
{ installmentId: "RMDHN_3M" },
{ $inc: { availableQuota: -1 } }
)
db.installmentPromoUsers.updateOne(
{ cif: "1AH3CU" },
{ $push: { usedInstallmentIds: "RMDHN_3M" } }
)
d) Transactions: If you need to update both collections atomically (i.e., either both updates succeed or both fail), consider using multi-document transactions. This ensures that the updates to both collections are treated as a single, atomic operation.
const session = db.client.startSession();
session.startTransaction();
try {
await db.installmentPromos.updateOne(
{ installmentId: "RMDHN_3M" },
{ $inc: { availableQuota: -1 } },
{ session }
);
await db.installmentPromoUsers.updateOne(
{ cif: "1AH3CU" },
{ $push: { usedInstallmentIds: "RMDHN_3M" } },
{ session }
);
await session.commitTransaction();
} catch (error) {
await session.abortTransaction();
throw error;
} finally {
session.endSession();
}
e) Optimistic Concurrency Control: If you’re concerned about conflicts between parallel write operations, you can implement optimistic concurrency control. This involves checking if the document has been modified since you last read it before applying your updates.
Hope this helps!