Your example check constraint indeed appears to work as advertised. Trying
UPDATE account SET balance = -1.00 where id = 1;
gives an ERROR message re:
new row for relation "account" violates check constraint ...Still it's not clear exactly what the author sees re: where postgres fails. I'll have to read the article again. With any luck someone more knowledgeable than I am will shed light on the question.
This paper: http://dl.acm.org/citation.cfm?id=1376690 outlines the general issue. This paper discusses Postgres's solution: http://drkp.net/papers/ssi-vldb12.pdf
Also, Peter Bailis's blog has info and links to papers if you want more detail (http://www.bailis.org/blog/when-is-acid-acid-rarely/)
What I don't know is about the particular problem the exchange encountered, and why postgres's isolation would not have prevented it. Based on the very brief descriptions of the problem that I've seen, it seems like postgres would have prevented it, but I don't have enough information to say for sure.
Think of a transaction that inserts a row representing a withdrawal, updates a materialized total balance, and checks that it's positive. Under snapshot isolation, two concurrent instances of this transaction could commit. The materialized balance would reflect only one of the debits however, and would be inconsistent vs queries that recompute the aggregate in full.
Postgres pre version 9.2-ish would allow this situation even in "serializable" mode. Later versions wouldn't.
The author didn't really show that this was true. He obviously understands isolation well, so I would tend to believe him, but it would be nice to see an example.
In a simple case (not sure that it matches the exchange's case), postgresql in any configuration will prevent this problem:
No matter what concurrent activity you have going on, it's impossible (as far as I know) to end up seeing a balance less than 0. That's actually true in any isolation mode that postgres supports (read committed, snapshot isolation, and truly serializable).Does someone have a counterexample, or more details about the case at the exchange that would not be solved by postgres?
I'd also like to point out that the postgres's implementation of true serializability performs quite well and there isn't much of a cost to using it over snapshot isolation.