Case 3 is the normal case for most reads in the database - think about it, the only data you're supposed to find in a database is committed data.
Case 4 is a problem because the transaction A (the first one) is reading data written by transaction B (the second), but B has not committed yet. If A acts on that data (and eventually commits), but B rolls back (or does another update on that data before committing), A will have "acted on" data that was never committed, i.e. never existed.
Scenario: Alice has $300 in her checking account, Bob has $250, negative balances are not allowed.
- Transaction A: transfer $700 from Alice to Peter
- Transaction B: transfer $500 from Bob to Alice
TB
starts, update's Alice's balance with +$500 (then goes off to sleep). TA
starts.
In case 3, TA
only reads committed data. So it sees Alice's starting balance of $300, and will roll back when it realizes that Alice's account would be overdrawn. All good. You can run each step of those transactions in the order you want if you read only committed data, neither transfer will post.
In case 4, TA
would read the uncommitted balance $800 from TB
, do the transfer and commit - it believes Alice has the funds. System state is corrupt at that point. TB
can't commit without breaking the "no negative balances allowed" rules. It can't rollback without also breaking that rule.