Postgres - Transaction Isolation
Transaction Isolation#
The most strict is Serializable, which is defined by the standard in a paragraph which says that any concurrent execution of a set of Serializable transactions is guaranteed to produce the same effect as running them one at a time in some order.
The Repeatable Read mode provides a rigorous guarantee that each transaction sees a completely stable view of the database
phenomena between concurrent transactions:
dirty read
- A transaction reads data written by a concurrent uncommitted transactionnonrepeatable read
- A transaction re-reads data it has previously read and finds that data has been modified by another transactionphantom read
- A transaction re-executes a query returning a set of rows that satisfy a search condition and finds that the set of rows satisfying the condition has changed due to another recently-committed transaction.serialization anomaly
- The result of successfully committing a group of transactions is inconsistent with all possible orderings of running those transactions one at a time.
Isolation Level | Dirty Read | Nonrepeatable Read | Phantom Read | Serialization Anomaly |
---|---|---|---|---|
Read uncommitted | Allowed, but not in PG | Possible | Possible | Possible |
Read committed | Not possible | Possible | Possible | Possible |
Repeatable read | Not possible | Not possible | Allowed, but not in PG | Possible |
Serializable | Not possible | Not possible | Not possible | Not possible |
Read commited is the default isolation level in postgres.
Isolation Levels#
READ COMMITED
- aSELECT
query sees only data committed before the query began; it never sees either uncommitted data or changes committed during query execution by concurrent transactions. HoweverSELECT
does see the effects of previous updates executed within its own transaction, even though they are not yet committed. Two successive SELECT commands can see different data, even though they are within a single transaction, if other transactions commit changes after the firstSELECT
starts and before the secondSELECT
starts.UPDATE
,DELETE
,SELECT FOR UPDATE
, andSELECT FOR SHARE
work in the same way - if a target row is updated or deleted by the time it is found it will wait for the other transaction to complete.REPEATABLE READ
- The Repeatable Read isolation level only sees data committed before the transaction began; it never sees either uncommitted data or changes committed during transaction execution by concurrent transactions. The snapshot is seen at the start of the transaction not of the current transaction statement. Applications using this level must be prepared to retry transactions due to serialization failures. The repeatable read transaction will be rolled back if anotehr transaction affects the rows and commits with a messageERROR: could not serialize access due to concurrent update
. The current transaction should be aborted and retried from the beginning.SERIALIZABLE
- the strictest isolation level. Sequential execution - one after the other. The same as repeatable read except that it monitors for conditions which could make execution of a concurrent set of serializable transactions behave in a manner inconsistent with all possible serial executions of those transactions.
Isolation Levels and Django#
With django, the default isolation level on postgres is:
default_transaction_isolation: 'read committed'
If you need repeatable read
or serializable
use:
import psycopg2.extensions
DATABASES = {
# ...
'OPTIONS': {
'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE,
},
}
Serializable is good for finance stuff.
Under higher isolation levels, your application should be prepared to handle exceptions raised on serialization failures