Питання 3 · Розділ 11

Що таке Read Uncommitted?

Уявіть ситуацію: 4. Транзакція Б працювала з неіснуючими даними (500)

Мовні версії: English Russian Ukrainian

🟢 Junior Level

Read Uncommitted — це найнижчий рівень ізоляції транзакцій. При цьому рівні одна транзакція може бачити зміни, внесені іншою транзакцією, навіть якщо вона ще не завершилася (не зроблен COMMIT).

Головна проблема — Dirty Read (Брудне читання)

Уявіть ситуацію:

  1. Транзакція А змінила баланс зі 100 на 500
  2. Транзакція Б прочитала баланс і бачить 500
  3. Транзакція А скасувалася (ROLLBACK) — баланс повернувся до 100
  4. Транзакція Б працювала з неіснуючими даними (500)

Коли використовується

Практично ніколи в реальних додатках. Іноді для швидкої приблизної статистики, коли точність не важлива.

Важливо

У PostgreSQL та Oracle цього рівня фактично немає — якщо ви його встановите, база автоматично переключить вас на Read Committed.


🟡 Middle Level

Основні характеристики

  • Аномалії: Допускає всі три — Dirty Read, Non-repeatable Read, Phantom Read
  • Продуктивність: Теоретично найшвидший рівень, оскільки немає overhead на ізоляцію
  • Блокування: Читання не блокується записом, запис не блокується читанням

Сценарій Dirty Read докладно

Час    Транзакція А               Транзакція Б (Read Uncommitted)
T1       BEGIN;
T2       UPDATE accounts SET
         balance = 500 WHERE id = 1;
T3                                    SELECT balance FROM accounts
                                      WHERE id = 1; -- Бачить 500!
T4       ROLLBACK;
T5                                    Працює з балансом 500,
                                      але реально він 100

Чому Б бачить 500? На Read Uncommitted СУБД не створює snapshot. Читання йде безпосередньо з поточної версії рядка, навіть якщо транзакція-автор ще не закомітила.

Чому це небезпечно

  • Фінанси: Рішення про кредит на основі непідтвердженого балансу
  • Склади: Бронювання товару, який ще не надійшов
  • Цілісність: Можна побачити дані, що порушують constraints (наприклад, від’ємний баланс, який буде відкачено)

SQL Server NOLOCK

У SQL Server на цьому рівні часто використовують хінт WITH (NOLOCK) у SELECT-запитах:

SELECT * FROM accounts WITH (NOLOCK);

Це дозволяє читати дані без встановлення shared locks, що дає ту саму семантику, що й Read Uncommitted.

Особливості в PostgreSQL та Oracle

PostgreSQL: Рівень Read Uncommitted фізично відсутній. Команда SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED мовчки переводить на Read Committed.

Oracle: Також не дозволяє опуститися нижче Read Committed. Гарантує відсутність брудного читання архітектурно.


🔴 Senior Level

Чому Read Uncommitted практично не використовується

Architecture Perspective

У сучасних MVCC-based системах (PostgreSQL, Oracle) dirty read prevention built-in на архітектурному рівні:

  • Readers always see committed versions only
  • Uncommitted changes create new tuple versions not visible to others
  • No additional overhead to prevent dirty reads — it’s free

When Read Uncommitted Might Be Acceptable

  1. Approximate analytics: “Скільки приблизно замовлень сьогодні?” — точність до 1-2% не критична
  2. Health checks / monitoring: Швидка перевірка стану без гарантії точності
  3. Development/debugging: Тимчасове використання для investigation

Hidden Costs of Read Uncommitted

Попри відсутність overhead на isolation:

  • Data corruption risk: Application logic може прийняти рішення на основі phantom data
  • Cascading errors: Wrong data → wrong decisions → more wrong data
  • Debugging nightmare: Intermittent bugs, hard to reproduce

Implementation Details у різних СУБД

SQL Server:

  • Read Uncommitted = NOLOCK = читання без shared locks
  • Може читати “in-flight” data з uncommitted pages
  • Risk of allocation order scans missing/miscounting rows

PostgreSQL:

  • Автоматичне elevation до Read Committed
  • На Read Committed: кожен оператор бачить snapshot на момент початку оператора
  • Zero overhead для prevention dirty reads завдяки MVCC

MySQL/InnoDB:

  • Підтримує Read Uncommitted буквально
  • Але undo log все одно зберігає committed versions
  • Minor overhead savings vs Read Committed

Production Recommendation

У більшості production-систем Read Uncommitted не потрібен. Винятки: approximate dashboards (графіки з допустимою похибкою), internal monitoring tools.

Alternative Approaches

Замість Read Uncommitted для performance:

  1. Read Committed з query optimization: Правильні індекси дають більший виграш
  2. Read replicas: Offload reporting queries до replica
  3. Materialized views: Pre-computed aggregates
  4. Caching layer: Redis/Memcached для approximate data

🎯 Шпаргалка для співбесіди

Обов’язково знати:

  • Read Uncommitted — найнижчий рівень ізоляції, допускає всі 3 аномалії
  • Головна проблема — Dirty Read: читання незакомічених даних, які можуть бути відкачені
  • У PostgreSQL та Oracle цього рівня немає — автоматичне elevation до Read Committed
  • Практично не використовується в production, крім approximate analytics та monitoring
  • SQL Server використовує хінт WITH (NOLOCK) для dirty reads
  • Dirty read особливо небезпечний: рішення приймаються на основі даних, яких «ніколи не існувало»

Часті уточнюючі питання:

  • Чому PostgreSQL не підтримує Read Uncommitted? — MVCC architecture: dirty read prevention безкоштовна
  • Коли Read Uncommitted допустимий? — Approximate dashboards, health checks, development/debugging
  • Що бачить транзакція на Read Uncommitted? — Незакомічені зміни інших транзакцій
  • Чим Read Uncommitted відрізняється від Read Committed? — RC не допускає dirty reads

Червоні прапорці (НЕ говорити):

  • “Read Uncommitted швидший за Read Committed” — у MVCC системах різниці немає
  • “Можна використовувати для фінансових звітів” — неприпустимий ризик corrupted data
  • “NOLOCK = безпечний спосіб читання” — NOLOCK може читати дублікати і пропускати рядки

Пов’язані теми:

  • [[2. Які рівні ізоляції транзакцій існують]]
  • [[7. Що таке брудне читання (Dirty Read)]]
  • [[4. Що таке Read Committed]]