Read committed behavior in PostgreSQL - Time & Space Complexity
Start learning this pattern below
Jump into concepts and practice - no test required
When using read committed behavior in PostgreSQL, we want to understand how the time to read data changes as the amount of data grows.
We ask: How does the database handle reading data when other transactions are changing it?
Analyze the time complexity of the following SQL query under read committed isolation.
BEGIN;
SELECT * FROM orders WHERE status = 'pending';
-- Other transactions may update orders concurrently
COMMIT;
This code reads all orders with status 'pending' while other transactions might be updating the table.
Look for repeated work done during the query execution.
- Primary operation: Scanning rows in the orders table to find those with status 'pending'.
- How many times: Once per query execution, scanning all relevant rows.
As the number of orders grows, the time to scan and read pending orders grows roughly in proportion.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 row checks |
| 100 | About 100 row checks |
| 1000 | About 1000 row checks |
Pattern observation: The work grows linearly with the number of rows scanned.
Time Complexity: O(n)
This means the time to read pending orders grows roughly in direct proportion to the number of rows checked.
[X] Wrong: "Read committed means the query always reads a fixed small number of rows quickly regardless of table size."
[OK] Correct: The query still scans rows to find matching data, so more rows mean more work, even if it sees only committed data.
Understanding how read committed isolation affects query time helps you explain database behavior clearly and shows you grasp how transactions impact performance.
What if we added an index on the status column? How would the time complexity change?
Practice
Read Committed isolation level guarantee in PostgreSQL?Solution
Step 1: Understand Read Committed isolation
Read Committed isolation level ensures that a transaction sees only data committed before the query began, avoiding dirty reads.Step 2: Compare options with definition
It only reads data that has been committed by other transactions. matches this definition exactly. The other options describe behaviors of other isolation levels or incorrect behaviors.Final Answer:
It only reads data that has been committed by other transactions. -> Option CQuick Check:
Read Committed = no dirty reads [OK]
- Confusing Read Committed with Read Uncommitted
- Thinking it locks rows until transaction ends
- Assuming it prevents phantom reads
Solution
Step 1: Recall correct syntax for setting isolation level
The correct syntax in PostgreSQL is:SET TRANSACTION ISOLATION LEVEL READ COMMITTED;Step 2: Check each option
SET TRANSACTION ISOLATION LEVEL READ COMMITTED; matches the correct syntax exactly. The other options have incorrect word order or missing keywords.Final Answer:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED; -> Option DQuick Check:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED; [OK]
- Mixing order of keywords
- Omitting 'ISOLATION' or 'LEVEL'
- Using BEGIN with isolation level incorrectly
Solution
Step 1: Understand Read Committed behavior on concurrent reads
Under Read Committed, a transaction sees only committed data. Uncommitted changes from other transactions are invisible.Step 2: Apply to scenario
Transaction 1's update is uncommitted, so Transaction 2 reads the original committed data before the update.Final Answer:
The original data before Transaction 1's update. -> Option AQuick Check:
Read Committed hides uncommitted changes [OK]
- Assuming dirty reads are allowed
- Thinking a read error occurs
- Believing the row is locked and unreadable
BEGIN; UPDATE accounts SET balance = balance - 100 WHERE id = 1; SELECT balance FROM accounts WHERE id = 1; COMMIT;But you notice the SELECT shows the updated balance even before COMMIT. Why?
Solution
Step 1: Understand transaction visibility in Read Committed
In Read Committed, a transaction sees its own changes immediately, even if not committed yet.Step 2: Apply to given code
The SELECT inside the same transaction sees the updated balance from the UPDATE before COMMIT.Final Answer:
Because the transaction reads its own uncommitted changes under Read Committed. -> Option AQuick Check:
Transaction sees own changes before commit [OK]
- Confusing Read Committed with Read Uncommitted
- Thinking SELECT ignores transaction boundaries
- Assuming UPDATE failed without checking
Solution
Step 1: Understand phantom reads and Read Committed
Read Committed does not prevent phantom reads (new rows appearing during a transaction).Step 2: Evaluate options to prevent phantom reads
Switching to Repeatable Read prevents phantom reads but changes the isolation level and may reduce concurrency. Increasing transaction timeout or committing after every statement does not prevent phantom reads. Using explicit row-level locks with SELECT FOR UPDATE keeps Read Committed while preventing changes to selected rows, mitigating phantom reads.Final Answer:
Use explicit row-level locks with SELECT FOR UPDATE. -> Option BQuick Check:
Row-level locks prevent phantom reads under Read Committed [OK]
- Assuming Repeatable Read is always best
- Ignoring phantom reads in Read Committed
- Thinking timeout affects phantom reads
