I just tested this on a local instance and it seemed to work as expected with defaults:
var session = db.getMongo().startSession()
var sessionColRef = session.getDatabase('TranTest').Test
session.startTransaction()
sessionColRef.updateOne(
{_id:1},
{
$set:{
house:false
}
}
)
sessionColRef.find()
So we’ve done an update to document 1 (yes, I know…it’s not an ObjectID).
If outside of that transaction I attempt to update the same document:
db.getCollection("Test").updateOne({_id:1}, {$set:{house:true}})
The update hangs, it cannot complete as there is a transaction locking that document.
If I update another field that the transaction had not changed then the update will go through
A .find in another session will not show this new property until the transaction is committed.
Upon the first transaction completing the second update can go through and writes house:true to the record.
If I wrap both updates in transactions so:
Session1 : Update house to 9
Session2 : Update house to ‘A’
If I try and commit session 2 I get a transaction aborted as the data has already been updated by another session.
I can commit session 1 which saves 9 to the house property.
Obviously you can also change the read and write isolation levels as per the documentation, but have a play and test out.
If you wrap everything in transactions it seems to work the way you want, but if the second update is run outside a transaction, it waits but then goes through overwriting the transaction update. If both were wrapped then the second update would fall over as the first transaction has already done an update on that record.