It should be executed in a single transaction.
But the query may be scheduled more than once.
According to the Calvin paper, there are two strategies here:
* Either, the write set of the query is considered to be {B,C}.
* Or the query if rewritten and scheduled several times,
the `if` operation beeing replaced by an assert operation,
until the assertion is indeed true, in which case the transaction proceeds using a smaller write set.
If not, the query is scheduled again after having been rewritten to match the current values.
In other words, if A equals 0 then the query is rewritten as `assert A == 0 then Write(B,1)`.
Otherwise the query is rewritten as `assert A != 0 then Write(C,2)`.
Months ago, I implemented a prototype after the Calvin paper and used the first strategy.
It may imply more contentions and even lock the whole dataset with queries like `Write(Read(A),a))`.
Sadly, such queries are not rare: updating a distributed index is the typical case.
Ah, yeah, I suspected it could be fixed with your first approach, but the second one also sounds plausible.
But if you go with the first option, then you can end up locking the entire database, as you pointed out with `write(read(A), _)`. Wouldn't your second option cause multiple transaction aborts until you find the rewrite that satisfies the assert? And in that case, the scheduler would need to know if the abort was actually caused by a faulty rewrite.
It would be interesting to know what Fauna does in these cases.
If I do `if(read(A) = 0) then write(B, 1) else write(C, 2)`, would that be executed in 1 or 2 transactions?