almessadi.
Back to Index

PostgreSQL Isolation Levels Decide What Concurrency Bugs You Tolerate_

Transactions are not automatically safe just because they use `BEGIN` and `COMMIT`. Isolation level determines which anomalies are still possible under load.

PublishedAugust 30, 2024
Reading Time7 min read

Wrapping code in a transaction is necessary. It is not the same as making the operation concurrency-safe.

That is where isolation levels matter. They define what one transaction is allowed to observe while other transactions are changing the same data.

If you never think about that, you eventually ship a system that is "correct" in local testing and subtly wrong under concurrent traffic.

Why the Default Is Not Always Enough

PostgreSQL defaults to READ COMMITTED. That is a good default for many workloads, but it still allows patterns that are surprising if your application logic assumes a fully stable view of data within a transaction.

The right question is not:

"Did we use a transaction?"

It is:

"What anomalies are still possible at this isolation level for this business rule?"

A Practical Example

Imagine two requests both trying to reserve the last available unit of stock.

If the application reads availability first, then decides whether to write later, the concurrency behavior depends heavily on how the transaction is structured and whether locking or stricter isolation is used.

A simplified pattern often looks like this:

BEGIN;

SELECT quantity
FROM inventory
WHERE sku = 'book-123';

UPDATE inventory
SET quantity = quantity - 1
WHERE sku = 'book-123';

COMMIT;

Whether that is safe depends on the surrounding logic, locks, retries, and isolation level. The transaction boundary alone does not answer the question.

What Senior Engineers Actually Do

They choose among:

  • simpler default isolation with careful locking
  • retry logic for serialization failures
  • stricter isolation only where the business rule justifies the cost

That is a much healthier posture than "always use serializable" or "the default is probably fine."

Trade-Offs

Stricter isolation can improve correctness guarantees, but it also:

  • increases contention
  • raises the likelihood of transaction retries
  • can reduce throughput under load

That is why isolation is an engineering trade, not a moral choice.

Further Reading