Does .snapshot() provide Snapshot Level Isolation?

(gaurav) #1

Hi there,

I wanted to confirm that .snapshot() on a transaction provides a true snapshot level isolation for get()/getRange() calls? The documentation simply says that this “reduces” conflicts but does not explicitly states the guarantees.

More precisely, if at some time t1, keys a and b have values 1 and 2 respectively, and a snapshot read operation was started at t1 on these keys. Concurrently, two other write transactions modified these keys as follows: tr2 (a=10, b=11) and tr3 (a=20, b=21).

If I understand correctly, under snapshot isolation, possible read value combinations should be:
i) a=1, b=2 OR
ii) a=10, b=11 OR
iii) a=20, b=21

Can I expect that only one of these possible combination of values will be returned? Or is there a possibility to get back value pairs like <a=1, b=10> or <a=1, b=21> etc.?


(Alex Miller) #2

If I understand your outlined case correctly, only (i) is possible, because tr2 and tr3 would commit at a version >t1. But yes, snapshot() gives you a consistent view of the database at t1.

The documentation, is attempting to state that a commit of tr2 or tr3 won’t cause tr1 to abort, because snapshot reads don’t manifest as conflicts to the transaction resolver. So if tr1 does a snapshot read of a and b at t1, writes it to sum and commits concurrently with tr2 and tr3, it’s valid for FDB to commit tr2, followed by tr3, followed by tr1, and the ending database state would be a=20, b=21, sum=3.

(gaurav) #3

Thanks for clarifying it.
Yes, FDB’s external consistency should guarantee outcome (i); whereas with a DB providing only Snapshot Isolation guarantee any of (i), (ii) or (iii) might have been a valid outcome.