The most basic level of transaction isolation is read committed.v It makes two guarantees:
- 1. When reading from the database, you will only see data that has been committed (no dirty reads).
- 2. When writing to the database, you will only overwrite data that has been committed (no dirty writes).
Let’s discuss these two guarantees in more detail.
No dirty reads
Imagine a transaction has written some data to the database, but the transaction has not yet committed or aborted. Can another transaction see that uncommitted data? If yes, that is called a dirty read .
Transactions running at the read committed isolation level must prevent dirty reads. This means that any writes by a transaction only become visible to others when that transaction commits (and then all of its writes become visible at once). This is illustrated in Figure 7-4, where user 1 has set x = 3, but user 2’s get x still returns the old value, 2, while user 1 has not yet committed.
Figure 7-4. No dirty reads: user 2 sees the new value for x only after user 1’s transaction has committed.
Some databases support an even weaker isolation level called read uncommitted. It prevents dirty writes, but does not prevent dirty reads.
There are a few reasons why it’s useful to prevent dirty reads:
- • If a transaction needs to update several objects, a dirty read means that another transaction may see some of the updates but not others. For example, in Figure 7-2, the user sees the new unread email but not the updated counter. This is a dirty read of the email. Seeing the database in a partially updated state is confusing to users and may cause other transactions to take incorrect decisions.
- • If a transaction aborts, any writes it has made need to be rolled back (like in Figure 7-3). If the database allows dirty reads, that means a transaction may see data that is later rolled back—i.e., which is never actually committed to the database. Reasoning about the consequences quickly becomes mind-bending.