This is part of it but versionstamp is substantially weirder. With an atomic add you know the key but not the value. With a versionstamp key you know the value but not the key. Which means that you need to block any gets or scans within the range where the key could be (mercifully bounded to the read version plus 5s) because you don’t know where exactly the key is supposed to be in that range, even though you know the value!
If you think about the actual use-case here (primary key), you would want to be able to use it (and compose with it) as a foreign key. So function #1 creates a struct with a relation, and function #2 can look up the foreign key from the RYW cache without knowing that it actually only exists in the RYW cache. Even though we don’t know the real versionstamp key this entire pattern can be implemented on top of a placeholder key without violating correctness. I mean, I think it can anyway. This stuff is hard.
Weirdly, even a range scan should be correct. There can’t be any versionstamp keys in our snapshot above the read version anyway (obvious invariant), so there are no other keys in that range to read and therefore the only key in a range scan of [read_version, read_version + 5000000) should be our key! Of course if any other keys get inserted then we abort anyway so reading that range is a terrible idea but it’s correct, which is the important part.
So the only case where you would actually run into problems is if a previous transaction lied and inserted a versionstamp key into the range (keys are just bytes after all). Then we don’t know where our key lines up compared to that key, so a read of that range violates correctness.
But, why would you do that?! If we’re storing structured data we know this situation will never arise, so a strict serializability violation shouldn’t happen, ever. So it’s a weird case, I think, where the safety mechanism is only needed because FDB has to support unstructured keys for a use case where the data will only ever be structured in practice. The tyranny of key value stores, I guess.
But I still feel like I might be missing something, so I could just be totally wrong.






















