Транзакции
22 вопросов и ответов в разделе Транзакции.
Вопросы этого раздела
- Расшифруйте каждую букву ACID
- Какие уровни изоляции транзакций существуют?
- Что такое Read Uncommitted?
- Что такое Read Committed?
- Что такое Repeatable Read?
- Что такое Serializable?
- Что такое грязное чтение (Dirty Read)?
- Что такое неповторяющееся чтение (Non-Repeatable Read)?
- Что такое фантомное чтение (Phantom Read)
- Что такое потерянное обновление (Lost Update)
- Какой уровень изоляции по умолчанию в PostgreSQL
- Какой уровень изоляции по умолчанию в MySQL
- Что такое Propagation в Spring
- Что делает Propagation.NESTED
- В чём разница между REQUIRED и REQUIRES_NEW
- Что такое аннотация @Transactional?
- На каком уровне можно использовать @Transactional?
- Что такое rollback в транзакциях?
- Какие исключения по умолчанию вызывают rollback?
- Как настроить rollback для checked exceptions?
- Что такое readonly транзакция?
- Что произойдёт при вызове @Transactional метода из другого метода того же класса?
Навигатор по разделу
22 вопроса для подготовки к собеседованию на Middle Java Developer.
📋 Все вопросы
🗺️ Карта зависимостей тем
┌──────────────────────────────────────────┐
│ БАЗА ТРАНЗАКЦИЙ (1-2) │
│ 1. ACID │
│ 2. Уровни изоляции обзор │
└──────────────────┬───────────────────────┘
│
┌──────────────────────────┼──────────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌────────────────────┐
│ УРОВНИ │ │ АНОМАЛИИ │ │ СУБД-СПЕЦИФИКА │
│ ИЗОЛЯЦИИ (3-6) │ │ (7-10) │ │ (11-12) │
│ 3. Read Uncom. │ │ 7. Dirty Read │ │ 11. PostgreSQL │
│ 4. Read Comm. │ │ 8. Non-rep. │ │ 12. MySQL │
│ 5. Repeat. R. │ │ 9. Phantom │ │ │
│ 6. Serializable│ │ 10. Lost Update │ │ │
└───────┬───────┘ └───────┬───────┘ └────────┬───────────┘
│ │ │
└────────────────────────┼────────────────────────┘
▼
┌──────────────────────────────────────────┐
│ SPRING TRANSACTION (13-17) │
│ 13. Propagation обзор │
│ 14. Propagation.NESTED │
│ 15. REQUIRED vs REQUIRES_NEW │
│ 16. @Transactional │
│ 17. Уровни @Transactional │
└──────────────────────────────────────────┘
│
┌────────────────────────┼────────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌────────────────────┐
│ ROLLBACK │ │ СПЕЦИАЛЬНЫЕ │ │ SELF-INVOCATION │
│ (18-20) │ │ (21) │ │ (22) │
│ 18. Rollback │ │ 21. ReadOnly │ │ 22. Self-invocation│
│ 19. Default │ │ │ │ proxy bypass │
│ rollback │ │ │ │ │
│ 20. Custom │ │ │ │ │
│ rollback │ │ │ │ │
└───────────────┘ └───────────────┘ └────────────────────┘
🎯 Рекомендуемый порядок изучения
🟢 Уровень Junior (недели 1-2)
| Шаг | Тема | Файлы | Цель |
|---|---|---|---|
| 1 | ACID | Q1 | Atomicity, Consistency, Isolation, Durability |
| 2 | Уровни изоляции | Q2 | 4 уровня, что защищают |
| 3 | Аномалии | Q7, Q8, Q9, Q10 | Dirty Read, Non-repeatable, Phantom, Lost Update |
| 4 | @Transactional база | Q16, Q18, Q19 | Что делает, rollback по умолчанию |
| 5 | PostgreSQL vs MySQL | Q11, Q12 | Дефолтные уровни, отличия |
🟡 Уровень Middle (недели 3-4)
| Шаг | Тема | Файлы | Цель |
|---|---|---|---|
| 1 | Read Committed vs Repeatable Read | Q4, Q5 | MVCC vs Next-Key Lock, snapshot timing |
| 2 | Serializable | Q6 | SSI, dependency graph, serialization failure |
| 3 | Propagation | Q13, Q15 | REQUIRED, REQUIRES_NEW, rollback-only mark |
| 4 | NESTED | Q14 | Savepoint, JTA fallback, L1 cache trap |
| 5 | @Transactional уровни | Q17 | Class vs Method vs Interface |
| 6 | Checked exceptions rollback | Q20 | rollbackFor, noRollbackFor |
| 7 | ReadOnly | Q21 | Dirty checking, replica routing, MVCC hint |
🔴 Уровень Senior (недели 5-6)
| Шаг | Тема | Файлы | Цель |
|---|---|---|---|
| 1 | Isolation internals | Q5, Q6 (Senior) | Gap Lock, predicate lock, SSI implementation |
| 2 | Lost Update deep dive | Q10 (Senior) | Write skew, EvalPlanQual, atomic SQL |
| 3 | Propagation mechanics | Q13, Q14, Q15 (Senior) | ThreadLocal, suspend/resume, connection handling |
| 4 | Deadlock scenarios | Q15 (Senior) | REQUIRED + REQUIRES_NEW deadlock timeline |
| 5 | Self-invocation | Q22 | Proxy bypass, exposeProxy, AspectJ |
| 6 | Production scenarios | Q9, Q16 (Senior) | Phantom in batch jobs, checked exception war stories |
🔗 Ключевые связи между темами
Тема: Уровни изоляции и аномалии
Q1 (ACID) → Q2 (Уровни обзор) → Q3 (Read Uncommitted) → Q4 (Read Committed)
↓ ↓ ↓
Q5 (Repeatable Read) → Q6 (Serializable) Q7 (Dirty Read)
↓ ↓ ↓
Q8 (Non-repeatable Read) → Q9 (Phantom Read) → Q10 (Lost Update)
Ключевые связи:
- Q2 ↔ Q7-Q10: Каждый уровень защищает от определённых аномалий
- Q4 ↔ Q8: Non-repeatable read возникает именно на Read Committed
- Q5 ↔ Q9: Phantom read предотвращается на Repeatable Read (в MySQL через Gap Lock)
Тема: Spring Transaction
Q13 (Propagation) → Q14 (NESTED) → Q15 (REQUIRED vs REQUIRES_NEW)
↓ ↓
Q16 (@Transactional) → Q17 (Уровни) → Q22 (Self-invocation)
Ключевые связи:
- Q13 ↔ Q15: Propagation определяет поведение при наличии внешней транзакции
- Q14 ↔ Q15: NESTED vs REQUIRES_NEW — savepoint vs независимый commit
- Q16 ↔ Q19: @Transactional rollback только для RuntimeException + Error
- Q22 ↔ Q13: Self-invocation bypass — прокси не участвует, propagation не работает
Тема: Rollback и специальные настройки
Q18 (Rollback) → Q19 (Default rollback) → Q20 (Custom rollback)
↓
Q21 (ReadOnly)
Ключевые связи:
- Q18 ↔ Q20: rollbackFor переопределяет дефолтное поведение
- Q19 ↔ Q20: Checked exceptions = commit по умолчанию → rollbackFor = Exception.class
- Q21 ↔ Q18: ReadOnly не делает rollback, но оптимизирует чтение
🎓 Шпаргалка: что знать для каждого уровня
🟢 Junior
- ACID: Atomicity (всё или ничего), Consistency (ограничения выполнены), Isolation (не мешают друг другу), Durability (сохранено после commit)
- 4 уровня изоляции: Read Uncommitted, Read Committed, Repeatable Read, Serializable
- Dirty Read = вижу незакоммиченные данные, Non-repeatable = значение изменилось между SELECT, Phantom = появились/исчезли строки
- PostgreSQL default = Read Committed, MySQL default = Repeatable Read
- @Transactional: rollback для RuntimeException, commit для checked exceptions
🟡 Middle
- Read Committed: snapshot на каждый SELECT → non-repeatable read возможен
- Repeatable Read: snapshot на всю транзакцию → phantom read возможен (в PostgreSQL через MVCC, в MySQL через Gap Lock — предотвращён)
- Propagation: REQUIRED (присоединяюсь), REQUIRES_NEW (новая, внешняя suspend), NESTED (savepoint)
- Self-invocation:
this.method()bypass-ит прокси → @Transactional не работает - ReadOnly: отключает dirty checking, hint оптимизатору, routing на реплику (если настроен)
🔴 Senior
- Serializable в PG = SSI (Serializable Snapshot Isolation), не блокирует чтение, но откатывает при RW-conflict cycles
- Lost Update: atomic SQL (
SET x = x - 1) решает проблему без locking - REQUIRES_NEW overhead: suspend ~2ms, new connection ~0.5ms, Session suspend ~2ms, resume ~2ms
- NESTED: не работает с JTA → fallback к REQUIRES_NEW. L1 cache trap после savepoint rollback
- Checked exception rollback: TransactionInterceptor видит исключение ДО catch → setRollbackOnly() → UnexpectedRollbackException
📝 Формат каждого файла
Каждый файл содержит:
- 🟢 Junior Level — базовое понимание, простые аналогии, примеры
- 🟡 Middle Level — внутренности, типичные ошибки, практические примеры
- 🔴 Senior Level — deep dive, edge cases, production experience, monitoring
- 🎯 Шпаргалка для интервью — ключевые тезисы, частые вопросы, красные флаги, связанные темы