" A customer issues a transaction to machine A that decrements the inventory. After this transaction completes, a different transaction is issued to machine B that reads the current inventory. On a single machine, the second transaction would certainly read the write of the first transaction. But now that they are running on separate machines, if the system does not guarantee consistent reads across machines, it is very much possible that the second transaction would return a stale value (e.g. this could happen if replication was asynchronous and the write from the first transaction has not yet been replicated from A to B). This stale read would not be a violation of serializability. It is equivalent to a serial order of the second transaction prior to the first. But since the second transaction was submitted after the first one completed, it is certainly a violation of strict serializability."<p>Isn't this a problem on all DBs that don't have strict serializability and can't it be solved by 2 Phase Commit ?
In the vote phase, the coordinator can also get the final balance from each replica, in that case if any balance differes it knows one of the replica isn't synced and aborts the transaction (user retries).<p>Another idea maybe (doesn't scale) -<p>Mark replicas as read only and the writes only go through one or a set of master nodes which guarantee that the state is up to date ?<p>Would love for an expert to chime in.
Their banking example is impossible under any system which guarantees serializability.<p>To guarantee serializability, the database system cannot assume anything about how some value is derived (unless it is something like a single stored procedure).<p>If I am playing the evil demon to show why their example is not valid under serializability, let us make a small modification to their example. Instead of just paying the babysitter, assume that our customer simply execute the following procedure twice as two separate transactions.<p><pre><code> begin transaction;
money = select money from bank where id=42;
if money % 2 == 0:
update bank set money=money-1 where id=42;
else:
update bank set money=money+2 where id=42;
commit;
</code></pre>
If money = 10 initially, there is precisely one valid end state for money, money = 11. However, using the logic from the article, it is supposedly valid for the second execution to read the old value for money. Therefore, both transactions end up writing money=9 which is clearly not possible under serializability, strict or not!<p>The key part of this is that the database has no idea what logic we are using to compute the new value of money.<p>The only time I could see strict serializability potentially being stronger than normal serializability is with cases where the client is executing a stored procedure and therefore the database can know exactly what logic the client is running.
Does Postgresql offer strict serializability?<p>With synchronous replication it should, since it waits till all replicas are in the same state(as far as I know), which makes it strict?
I'd always known this as wall-clock serializability. Not a technical sounding term but very descriptive.<p>I'm not sure I know of any traditional RDBMSes that run in Serializable but not Strict Serializable mode. It's only the horizontally distributed ones that squeeze more performance that seem to choose the trade-off for performance. CockroachDB (-is-)was the notable one that used SNAPSHOT isolation permitting write skew. "As of CockroachDB 2.1, SNAPSHOT isolation is no longer supported, and SERIALIZABLE SNAPSHOT is now simply known as SERIALIZABLE." Good to know.
Doesn't strict serializability solve only part of the problem? If X finishes before Y starts, then X must come before Y in serial order. But if there is some overlap between X and Y in the first place, then again some serial order is picked (serializability already guarantees that), but strict serializability still does not define which of the two possible orders gets picked. So at least query-level replication would suffer from the same problems as before.