Isolation level quyết định transaction có thể thấy dữ liệu uncommitted của transaction khác không.
| Level | Dirty Read | Non-repeatable Read | Phantom Read |
|---|---|---|---|
| READ_UNCOMMITTED | ✅ có | ✅ có | ✅ có |
| READ_COMMITTED (default) | ❌ không | ✅ có | ✅ có |
| REPEATABLE_READ | ❌ không | ❌ không | ✅ có |
| SERIALIZABLE | ❌ không | ❌ không | ❌ không |
- Dirty Read: đọc dữ liệu chưa commit của tx khác.
- Non-repeatable Read: đọc cùng row 2 lần → kết quả khác (vì tx khác update giữa chừng).
- Phantom Read: query lại → số row khác (vì tx khác insert/delete).
// Default
@Transactional(isolation = Isolation.READ_COMMITTED)
// Đọc row nhiều lần trong cùng tx → cần consistent
@Transactional(isolation = Isolation.REPEATABLE_READ)
// Cao nhất — tất cả tx serial hóa, chậm, tránh dùng
@Transactional(isolation = Isolation.SERIALIZABLE)Thực tế:
- READ_COMMITTED phù hợp 90%+ use case.
- REPEATABLE_READ khi cần đọc cùng data nhiều lần trong tx (tính toán tổng, report).
- SERIALIZABLE chỉ khi tuyệt đối không chấp nhận phantom read (financial ledger).
Lưu ý: Postgres default là READ_COMMITTED. Isolation level phụ thuộc DB — không phải DB nào cũng implement đủ 4 level.
Isolation level determines whether a transaction can see uncommitted data from other transactions.
| Level | Dirty Read | Non-repeatable Read | Phantom Read |
|---|---|---|---|
| READ_UNCOMMITTED | ✅ yes | ✅ yes | ✅ yes |
| READ_COMMITTED (default) | ❌ no | ✅ yes | ✅ yes |
| REPEATABLE_READ | ❌ no | ❌ no | ✅ yes |
| SERIALIZABLE | ❌ no | ❌ no | ❌ no |
- Dirty Read: reading uncommitted data from another transaction.
- Non-repeatable Read: reading the same row twice returns different results (another tx updated it).
- Phantom Read: re-querying returns a different row count (another tx inserted/deleted rows).
// Default
@Transactional(isolation = Isolation.READ_COMMITTED)
// Reading the same row multiple times within a tx → need consistency
@Transactional(isolation = Isolation.REPEATABLE_READ)
// Highest — fully serialises all transactions, slow, avoid unless necessary
@Transactional(isolation = Isolation.SERIALIZABLE)In practice:
- READ_COMMITTED suits 90%+ of use cases.
- REPEATABLE_READ when reading the same data multiple times in one tx (totals, reports).
- SERIALIZABLE only when phantom reads are absolutely unacceptable (financial ledgers).
Note: Postgres defaults to READ_COMMITTED. Isolation levels depend on the DB — not all DBs implement all four levels.