Logo

dev-resources.site

for different kinds of informations.

Understanding PostgreSQL Isolation Levels

Published at
1/7/2025
Categories
sitereliabilityengineering
postgressql
banking
Author
mohamed_hamdi_2590116d3ec
Author
25 person written this
mohamed_hamdi_2590116d3ec
open
Understanding PostgreSQL Isolation Levels

In PostgreSQL, transaction isolation levels determine how transactions are isolated from one another, affecting how they handle dirty reads, non-repeatable reads, and phantom reads. The right choice of isolation level can ensure data consistency in a multi-user environment while balancing performance.

PostgreSQL Isolation Levels

Read Committed (default isolation level)
Repeatable Read
Serializable (highest isolation level)

Each level controls the visibility of uncommitted data from other transactions and defines the kinds of concurrency anomalies you may encounter.

Read Committed

Read Committed is the default isolation level in PostgreSQL. It ensures that each query within a transaction sees only committed data up to the point when the query is executed. This level allows non-repeatable reads because a value read by one query might be changed by another transaction in between queries within the same transaction.

Characteristics

Dirty Reads: Prevented (you cannot read uncommitted data).
Non-repeatable Reads: Allowed (data read may change between queries).
Phantom Reads: Allowed (rows may appear or disappear).

When to Use

This level is sufficient for many read-heavy operations, where performance is important, but perfect consistency between consecutive reads is not critical.

Example

When a customer checks their balance, it’s possible that another transaction could modify the balance between their queries.

-- Set Isolation Level to Read Committed
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- Start Transaction
BEGIN;  
-- Query 1: Read current balance (it may change in subsequent queries)
SELECT balance FROM accounts WHERE account_id = 1;
-- Query 2: Deduct balance (another transaction may modify balance in between)
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- End Transaction
COMMIT;  
Enter fullscreen mode Exit fullscreen mode

Scenario

If another transaction commits a change to the balance between the first SELECT and the UPDATE statement, the customer may see different results depending on the timing of their queries.

This isolation level is commonly used for user-facing applications where real-time performance is needed but perfect consistency across multiple reads isn’t critical.

Repeatable Read

Repeatable Read ensures that once a transaction reads a row, it will see the same value throughout the entire transaction, preventing non-repeatable reads. However, phantom reads are still possible (new rows might appear or disappear if other transactions insert or delete rows that match the transaction’s query criteria).

Characteristics

Dirty Reads: Prevented.
Non-repeatable Reads: Prevented (data seen by a query within the transaction remains unchanged for the rest of the transaction).
Phantom Reads: Allowed (new rows might appear between queries).

When to Use

Repeatable Read is ideal for multi-step transactions, like transferring funds between accounts, where the data should remain consistent during the entire process.

Example

A user initiates a fund transfer from one account to another, and we ensure that the balance doesn’t change during the transaction.

-- Set Isolation Level to Repeatable Read
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- Start Transaction
BEGIN;  
-- Query 1: Check the source account balance (it will stay the same throughout the transaction)
SELECT balance FROM accounts WHERE account_id = 1;
-- Query 2: Deduct funds from the source account
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- Query 3: Add funds to the destination account
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
-- End Transaction
COMMIT; 
Enter fullscreen mode Exit fullscreen mode

Scenario

In Repeatable Read, the balance of both accounts remains locked for the duration of the transaction. If another transaction tries to modify the balances in the middle of the transfer, it will be blocked until the current transaction is committed.

This isolation level is useful in scenarios where data consistency is critical across multiple queries but where it’s acceptable for new rows to be inserted by other transactions.

Serializable

Serializable is the highest isolation level and provides the strictest consistency. It ensures that transactions behave as if they were executed serially, one after the other, meaning no other transactions can interfere with the current transaction. This prevents all anomalies, including dirty reads, non-repeatable reads, and phantom reads.

Characteristics

Dirty Reads: Prevented.
Non-repeatable Reads: Prevented.
Phantom Reads: Prevented.

When to Use

Serializable is the best choice for critical financial transactions where absolute consistency is required, such as money transfers or loan disbursements. It ensures that no other transaction can alter the data being processed during the transaction.

Example

When transferring money between two accounts, you need to ensure that the transaction will not encounter any anomalies, such as double-spending or inconsistent balances.

-- Set Isolation Level to Serializable
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- Start Transaction
BEGIN;  
-- Query 1: Read source account balance (locks it for the transaction)
SELECT balance FROM accounts WHERE account_id = 1;
-- Query 2: Deduct amount from source account
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- Query 3: Add amount to destination account
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
-- End Transaction
COMMIT; 
Enter fullscreen mode Exit fullscreen mode

Scenario

With Serializable isolation, PostgreSQL ensures that the transaction behaves as though it were the only transaction running. If another transaction tries to modify the same accounts during this process, it will be blocked until the current transaction is complete.

This isolation level guarantees the highest level of data integrity and is crucial for applications where financial accuracy and consistency are paramount, such as transfer of large sums of money.

Practical Considerations

Performance vs. Consistency

For customer-facing applications, where performance is important but absolute consistency is less critical, use Read Committed.

For financial transactions that involve multiple operations (e.g., fund transfers), use Repeatable Read.

For critical transactions, such as large money transfers, use Serializable to ensure no anomalies.

Concurrency and Locking

Lower isolation levels like Read Committed allow higher concurrency but increase the chance of encountering anomalies.

Serializable ensures the highest consistency but may cause blocking and reduced throughput due to the strict locking mechanisms.
Exception Handling:

In Serializable, PostgreSQL might raise a serialization failure exception if it detects that two transactions would conflict in a way that violates the serializability guarantees. In such cases, you can retry the transaction.

-- Example of handling serialization failure in a transaction
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN;
-- Perform operations
COMMIT;
-- If a serialization failure occurs, you can retry the transaction
EXCEPTION WHEN serialization_failure THEN
    ROLLBACK;
    -- Retry logic here
Enter fullscreen mode Exit fullscreen mode

PostgreSQL Isolation Levels

Conclusion

Choosing the correct isolation level in PostgreSQL is crucial for ensuring data consistency, especially in banking and financial applications. The isolation level determines how transactions interact with each other, balancing between concurrency and consistency. For high-concurrency environments, Read Committed is often enough, but for critical operations like fund transfers or loan processing, Serializable isolation provides the strongest guarantees to avoid inconsistencies.

By carefully selecting the right isolation level based on your specific needs, you can ensure that your application behaves reliably while providing the right balance of performance and data integrity.

postgressql Article's
30 articles in total
Favicon
GraphDB for CMDB
Favicon
Not able to connect to PostgreSQL server on Fedora
Favicon
Master Test Data Generation With dbForge Studio for PostgreSQL
Favicon
Exploring the Power of Full-Stack Development with Next.js and Prisma
Favicon
Bringing PostgreSQL Query Issues to Light with Insightful Visuals
Favicon
POSTGRESQL - ÍNDICE GIN NA PRÁTICA
Favicon
Reading PostgreSQL Query Plans Brought to a New Level
Favicon
Understanding PostgreSQL Isolation Levels
Favicon
How to Activate and Enable the PostgreSQL Service on Your Kali Linux System
Favicon
Mastering charts and database visualization with ChartDB
Favicon
The Best Ways to Connect to a PostgreSQL Database
Favicon
Hey, welcome to my blog
Favicon
How to Create a Database and Always Connect to It in PostgreSQL Without Needing Superuser Access
Favicon
03. ரிலேஷனல் டேட்டாபேஸ் மாடல் என்றால் என்ன? What is Relational Database Model ? (RDBMS)
Favicon
04. தரவு ஒருங்கிணைவு (Data Integrity)
Favicon
02. DBMS என்றால் என்ன? What is a DBMS?
Favicon
How To Use Materialized Views
Favicon
PostgreSQL Secrets You Wish You Knew Earlier
Favicon
Reading Parallel Plans Correctly
Favicon
New PostgreSQL ORM for Golang: Enterprise
Favicon
Migrate 🪳Coackroach DB into Postgres🐘
Favicon
💡 Database Development: It’s Not Just About Querying!
Favicon
Building Real-Time Data Pipelines with Debezium and Kafka: A Practical Guide
Favicon
01. தரவுத்தளம் எவ்வாறு உருவானது, அதன் தேவை என்ன? How did the database come about, What is its need?
Favicon
Data inconsistency in AWS Amazon Aurora Postgres solved with Local Write Forwarding?
Favicon
PostgreSQL vs. MySQL
Favicon
How To Handle Custom S/DQL Queries On Different Database Engine with DoctrineExpression
Favicon
Deploying PostgreSQL on Kubernetes: 2024 Guide
Favicon
Step-by-Step Guide to Installing PostgreSQL on Arch Linux
Favicon
Remedy for Poor-Performing SQL Queries

Featured ones: