I have a FaunaDB which I would like to interact with as a document store. I have a single api which:
- Reads an entire document from FaunaDB
- Mutates that data arbitrarily based on input to the api
- Writes the mutated back while guaranteeing the data has not been mutated
- Error or retry if the read was not current when attempting to write
In Postgres to guarantee consistency I would simply use a where clause. Since Fauna is distributed I assume the equivalent is more nuanced, for example my understanding is that CosmosDB writes idiomatically send the eTag of the read to check to guarantee consistency.
In fauna all write transactions run through the transaction pipeline at strict serializable isolation. So all we need to maintain the desired invariant over our two transactions is to make sure we tie our write to a read that checks that the document hasn't been updated while we were futzing around in our own code. Let
$ref
be some ref that we have magical knowledge of. Let$ts
be the result ofSelect("ts", Get($ref))
during our original read transaction. Let$expr
be whatever we want to update our document to. Then:Of course, you probably want to do something smarter: It's probably a better idea on failure to return the updated document. Exactly how you want to structure that is up to you but
Would work well enough, you'd just need some case analysis in on the resulting object to see if you had the doc or a failure. You could even get all fancy and move the instance read into a
Let
but the runtime characteristics are much the same (the read is cached locally during eval, we won't do it twice).