Transaction with Read Concern 'local' doesn't behave as expected

Hi, I created some tests to better understand transactions.
This is one of the tests, and what I did:

  1. Start Session, Start Transaction
  2. Find document id:1 with a random integer. Logs it.
  3. Another process outside the transaction find the same document and modify the integer
  4. Repeat step 2.

I expected to log number X, modified to number Y and after that on the second find to see the Y again.
But the transaction is acting as a snapshot when I`m clearly setting readConcern to local.

I there anything else that I’m missing here? Shouldn’t the last find read the latest document state?

Below is the logging of this script.

  writeConcern: WriteConcern { w: 'majority' },
  readConcern: ReadConcern { level: 'local' },
  readPreference: ReadPreference {
    mode: 'primary',
    tags: undefined,
    hedge: undefined,
    maxStalenessSeconds: undefined,
    minWireVersion: undefined
find with session 684
update without session 987
wait for 5 seconds
find with session 684
find after transaction commit 987
Ending Session```

Might be related to this: Isolation in transactions

As i recall, Mongodb document doesn’t say much about transaction isolation (e.g. unlike the detailed info in sql databases).

In SQL databases, every single statement is a transaction implicitly. I’m guessing this is also true for a “simple operation” in nosql world. (e.g. updateOne).

This is the manual reference of this test:

But it should happen with readConcern snapshot and not with readConcern local. Just like the manual example.

I believe I found a reason, but if anyone with more experience knows if this is correct, please chime in.
I had some misconceptions about how transactions work:

  1. It seems that readConcern is applied to the transaction as whole, as if everything is one big operation. So the readConcern local will not read local (new data) on each find statement, it will read local at the moment that I call session.startTransaction.

  2. From this moment on, the transaction will read a snapshot of the data. Which has nothing to do with readConcern:snapshot - The naming here is very confusing.

This became more clear on WiredTiger documentation:
WiredTiger: Managing the transaction timestamp state

  1. So, if the transaction readTimestamp is set to something data returned until that point in time, if not set or set to zero: data returned is at the point in time of the the transaction start.

Now this is my operation with readConcern:local:

This is with readConcern:snapshot

This is with readConcern:majority

  1. Difference between snapshot and majority when using transactions is basically shard snapshot consistency with the former. (something like shardedSafeMajority)

I believe that’s it.
If anyone has more experience with this topic, don’t be shy.

Good finding. Maybe that’s why only a transaction level read concern can be set instead of for individual operations.

MongoDb is a complex software, so it’s understandable that documentation will miss something.