Repeatable read helps keep your data consistent during a transaction by making sure you see the same data each time you look, even if others change it.
Repeatable read behavior in PostgreSQL
Start learning this pattern below
Jump into concepts and practice - no test required
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- your queries here
COMMIT;BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; to start a transaction with repeatable read isolation.BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; SELECT * FROM accounts WHERE user_id = 1; SELECT * FROM accounts WHERE user_id = 1; COMMIT;
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; UPDATE accounts SET balance = balance + 100 WHERE user_id = 1; SELECT balance FROM accounts WHERE user_id = 1; COMMIT;
This example shows that inside the repeatable read transaction, both SELECT queries see the same balance value, even if another session changes it between the queries.
CREATE TABLE accounts (user_id INT PRIMARY KEY, balance INT); INSERT INTO accounts VALUES (1, 1000); BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; SELECT balance FROM accounts WHERE user_id = 1; -- Imagine another session updates balance to 2000 here SELECT balance FROM accounts WHERE user_id = 1; COMMIT;
Repeatable read prevents non-repeatable reads but does not prevent phantom reads (new rows appearing).
It uses a snapshot of the database taken at the start of the transaction.
Other transactions can still change data, but you won't see those changes inside your transaction.
Repeatable read keeps your data consistent during a transaction by showing the same snapshot.
It helps avoid seeing changes made by others while you work.
Use it when you need stable data for multiple queries in one transaction.
Practice
What does the REPEATABLE READ isolation level guarantee in PostgreSQL?
Solution
Step 1: Understand Repeatable Read isolation
Repeatable Read ensures that all queries in a transaction see the same snapshot of data, preventing changes made by others from appearing during the transaction.Step 2: Compare options with definition
It ensures all queries in a transaction see the same data snapshot. matches this definition exactly. Options B, C, and D describe behaviors not related to Repeatable Read.Final Answer:
It ensures all queries in a transaction see the same data snapshot. -> Option AQuick Check:
Repeatable Read = Same snapshot [OK]
- Confusing Repeatable Read with Read Uncommitted
- Thinking it locks all rows
- Assuming auto-commit after each query
Which of the following is the correct way to start a transaction with REPEATABLE READ isolation level in PostgreSQL?
BEGIN; -- your queries COMMIT;
Solution
Step 1: Recall correct syntax for setting isolation level
In PostgreSQL, you start the transaction with BEGIN, then set the isolation level for that transaction using SET TRANSACTION ISOLATION LEVEL.Step 2: Match options to syntax
BEGIN; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; correctly shows BEGIN; then SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;. SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN; sets isolation before BEGIN which is invalid. BEGIN ISOLATION LEVEL REPEATABLE READ; uses invalid syntax. BEGIN; SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ; sets session level, not transaction level.Final Answer:
BEGIN; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -> Option CQuick Check:
Set isolation after BEGIN = BEGIN; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; [OK]
- Trying to set isolation before BEGIN
- Using BEGIN with isolation level directly
- Confusing session and transaction level commands
Consider this sequence in PostgreSQL with REPEATABLE READ isolation:
-- Transaction 1 BEGIN; SELECT balance FROM accounts WHERE id = 1; -- returns 100 -- Transaction 2 BEGIN; UPDATE accounts SET balance = 200 WHERE id = 1; COMMIT; -- Back to Transaction 1 SELECT balance FROM accounts WHERE id = 1; COMMIT;
What will be the result of the second SELECT in Transaction 1?
Solution
Step 1: Understand snapshot behavior in Repeatable Read
Transaction 1 sees a consistent snapshot from its start. Changes committed by Transaction 2 after Transaction 1 began are not visible.Step 2: Apply to the SELECT query
The first SELECT returned 100. The second SELECT in the same transaction will also return 100, ignoring the update committed by Transaction 2.Final Answer:
100 -> Option BQuick Check:
Repeatable Read = same snapshot = 100 [OK]
- Expecting updated value 200 inside same transaction
- Thinking it causes error on concurrent update
- Assuming NULL if data changed
Given this transaction in PostgreSQL:
BEGIN ISOLATION LEVEL REPEATABLE READ; UPDATE products SET stock = stock - 1 WHERE id = 10; SELECT stock FROM products WHERE id = 10; COMMIT;
But you get an error: ERROR: syntax error at or near "ISOLATION". What is the fix?
Solution
Step 1: Identify syntax error cause
PostgreSQL does not support specifying isolation level directly in BEGIN statement.Step 2: Correct syntax to set isolation level
You must first BEGIN; then run SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; before queries.Final Answer:
Change to BEGIN; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -> Option AQuick Check:
Set isolation after BEGIN, not inside [OK]
- Trying to put isolation level inside BEGIN
- Using unsupported START TRANSACTION syntax
- Setting session level instead of transaction level
You want to run multiple SELECT queries in a transaction and ensure the data does not change during the transaction, but you also want to allow other transactions to update data concurrently without blocking. Which isolation level should you choose in PostgreSQL?
Solution
Step 1: Understand isolation levels and concurrency
READ COMMITTED allows seeing changes committed during the transaction, so data can change between queries. SERIALIZABLE is strict and may block or abort concurrent updates. READ UNCOMMITTED is not supported in PostgreSQL.Step 2: Match requirement to isolation level
REPEATABLE READ provides a stable snapshot for all queries in the transaction, preventing data changes from appearing, while allowing concurrent updates without blocking reads.Final Answer:
REPEATABLE READ -> Option DQuick Check:
Stable snapshot + concurrency = REPEATABLE READ [OK]
- Choosing SERIALIZABLE which blocks more
- Thinking READ COMMITTED prevents data changes
- Assuming READ UNCOMMITTED exists in PostgreSQL
