Skip to main content

PostgreSQL transaction isolation

· 3 min read
Andrey Ganyushkin

PostgreSQL basics

Book to read: PostgreSQL 14 изнутри, Егор Рогов

A bit more details about transaction isolation in PostgreSQL database.

Transaction isolation anomalies

Different levels of "Transaction isolation" differ from each other by the presence or absence of anomalies.

lost update

Two transactions read one row and update this row independently (with original data) and commit one by one. As result we can see only result from last commited transaction which was allied to original data.

dirty read

Appears when the transaction (t2) reads uncommitted data from other transaction (t1). But there is no guarantee that (t1) will be commited successfully.

non-repeatable read

Transaction (t1) can read different data in two different read operations if between first and second reads some any changes will be commited from other (t2) transaction.

phantom read

Same like "non-repeatable read" but in row lavel.

Transaction (t1) can find different set of rows in two different searches if between first and second search (read rows, select, find by selectoror or without), insert or delete operations will be commited from other (t2) transaction.

read skew

note: Read Uncommitted is not possible in postgreSQL.

Transaction (t1) works and update some fields. Transaction (t2) read the same fields. (t2) can read some fields when (t1) is working and get old (not updated) version and read some fields after (t1 commit) and it will be new (updated versions). As result (t2) will work with not updated and updated versions. It will cause the inconsistency.

write skew

Two transactions (t1) and (t2) can read one field, make some desition and write results in other fields. Each of this result fields can be valid but both results together can broke consistency.

The main cause here it is parallel decision which was based on one original value and complex constraint.

reading transcription only

If we have three parallel transactions: (t1 write) (t2 write), (t3 read).

(t3 read) can get inconsistency data because (t1 write) & (t2 write) in parallel can update this data and for (t1) & (t2) it is ok, because they are working with original values and they can be aligned as sequence. But for (t3) we can't guarantee which data will be available for this transaction.

Snapshot Isolation, SI

Modern approach to organize isolation between transactions without locks.

A special version of SI is implemented in PostgreSQL - MVCC (Multiversion Concurrency Control).

In snapshot isolation we can have only two types of anomalies: write skew and reading transcription only

Transaction isolation

Read Uncommitted

anomalies: dirty read, non-repeatable read, phantom read, other

In this transaction we will read uncommitted data from other transactions.

In PostgreSQL this isolation can be selected but works like Read Committed

Read Committed

anomalies: non-repeatable read, phantom read, other

In transaction we will read changes from other transactions only if this changes was committed. But it may cause non-repeatable read.

Repeatable Read

anomalies: phantom read, other

There is no effects by non-repeatable read but phantom read still can happens.

Serializable

This mode should avoid any anomalies. But your application must be ready to retry transactions.


Conclusion

We must be careful to use databases... :(