Давайте поговоримо про щось, з чим стикається кожен розробник, але, ймовірно, не багато хто насправді розуміє: Ізоляція в базах даних. Це одна з тих основоположних концепцій, яка, коли її освоїш, рятує від безлічі головних болей (і сесій налагодження о 2 ночі).
Ізоляція є однією з основних складових моделі ACID — Атомарність, Узгодженість, Ізоляція, Тривалість — і зазвичай асоціюється з SQL базами даних. Якщо ви працюєте з NoSQL базами даних, ситуація дещо інша, оскільки вони часто надають пріоритет іншим принципам (як от eventual consistency). Але для SQL баз даних ізоляція — це те, що змінює гру. Давайте розберемося в цьому і зробимо це доступно та (сподіваюся) цікаво.
Що таке ізоляція?
Уявіть, що ви знаходитеся на кухні з кількома кухарями, кожен працює над своїми стравами, але всі вони використовують однакові інгредієнти. Без правил виникла б хаос: один кухар може забрати останнє яйце, поки інший ще розбиває його. Ізоляція гарантує, що кожен кухар працює по черзі, і його інгредієнти не будуть змінюватися, поки він не закінчить.
В термінах баз даних, ізоляція гарантує, що транзакції (наприклад, ваші операції, такі як читання, запис або оновлення даних) не заважатимуть одна одній. Це як якщо кожна транзакція має власну "пузирку", в якій вона може працювати, не хвилюючись про те, що роблять інші.
Коротка нотатка про ACID і BASE
У той час як SQL бази даних дотримуються моделі ACID, NoSQL бази даних часто орієнтуються на BASE (Основний доступ, М’який стан, Врешті-решт узгодженість). Ця різниця означає, що SQL бази даних краще підходять для додатків, де потрібна сувора узгодженість (наприклад, фінансові системи), тоді як NoSQL бази виділяються в ситуаціях, де важлива висока доступність і масштабованість (наприклад, соціальні мережі).
Чому вам варто звертати на це увагу
Уявіть картину: у банківському додатку два користувачі намагаються одночасно зняти гроші з одного й того ж рахунку. Без ізоляції обидва можуть побачити однаковий початковий баланс і зняти більше грошей, ніж є насправді. Ой.
Ізоляція запобігає цьому, гарантуючи, що транзакції не перешкоджають одна одній. Однак це не універсальне рішення — існують рівні ізоляції, які збалансовують продуктивність і узгодженість.
Неприємні явища при читанні
Ось тут починається цікаве. Без належної ізоляції можуть виникати дивні речі, коли транзакції взаємодіють між собою. Давайте розглянемо деякі з найпоширеніших проблем:
1. Брудні читання
Брудне читання виникає, коли одна транзакція читає дані, які були змінені іншою транзакцією, але ще не зафіксовані. Це як підслухати неповне речення — ви можете на нього діяти, лише щоб згодом дізнатися, що співрозмовник передумав.
Приклад: Транзакція A оновлює баланс банківського рахунку з $100 до $150, але ще не зафіксувала зміни. Транзакція B читає баланс як $150 і діє за цією інформацією. Якщо транзакція A скасовується, то транзакція B діяла на неправильних даних.
Брудне читання
2. Невідтворювані читання
Це трапляється, коли ви двічі читаєте ті ж самі дані в межах однієї транзакції, але дані змінюються між читаннями, оскільки інша транзакція їх змінила.
Приклад: Транзакція A читає ціну продукту як $10. Тим часом, Транзакція B оновлює ціну до $12 і зафіксовує зміни. Якщо Транзакція A читає ціну знову, вона побачить $12, що є непослідовним в рамках однієї транзакції.
Приклад транзакцій з невідтворюваними читаннями
3. Привиди читання
Привиди читання виникають, коли транзакція читає набір рядків, а інша транзакція вставляє рядки, що відповідають тій самій умові запиту.
Приклад: Транзакція A читає всі замовлення, зроблені сьогодні. Поки вона виконується, Транзакція B додає нове замовлення.
Якщо Транзакція A запитує знову, нове замовлення з’являється, порушуючи узгодженість.
4. Втрачені оновлення
Це класичний кошмар. Втрачені оновлення відбуваються, коли дві транзакції одночасно оновлюють однакові дані, і одна перезаписує зміни іншої, не помічаючи цього.
Приклад: Транзакція A та Транзакція B обидві читають кількість товару як 10. A додає 5, а B віднімає 3. Якщо B підтверджує зміни першою, а A підтверджує після, кінцевий запас може невірно показувати 15 замість 12.
Рівні ізоляції: вибір вашої страховки
Рівні ізоляції визначають, яку захищеність ви отримаєте від вищеописаних проблем.
1. Read Uncommitted (Читання без підтвердження)
- Що дозволяє: Брудні читання (ох!).
- Використання: Рідко, якщо взагалі. Це швидко, але ризиковано.
2. Read Committed (Читання з підтвердженням)
- Що забезпечує: Відсутність брудних читань. Ви бачите лише підтверджені зміни.
- Використання: Більшість систем використовують це за замовчуванням, досягаючи балансу між узгодженістю та продуктивністю.
3. Repeatable Read (Повторюване читання)
- Що забезпечує: Відсутність брудних та неповторюваних читань. Дані, які ви прочитали, не змінюватимуться протягом транзакції.
- Використання: Чудово підходить для фінансових систем, де узгодженість між читаннями має критичне значення.
4. Serializable (Серіалізоване)
- Що забезпечує: Абсолютна ізоляція. Транзакції виконуються так, ніби вони відбуваються одна за одною.
- Використання: Коли правильність має вирішальне значення, навіть за рахунок продуктивності (наприклад, банківські перекази).
Як зміна рівня ізоляції впливає на баланс між продуктивністю та узгодженістю
Заключні думки: чому ізоляція важлива
Ізоляція — це невизнаний герой проектування баз даних, який тихо зберігає вашу узгодженість даних і надійність додатків. Незалежно від того, чи ви тільки починаєте, чи будуєте високо конкурентну систему, розуміння ізоляції допоможе вам уникнути безлічі помилок (і безсонних ночей).
Пам’ятайте, річ не в тому, щоб вибрати "найкращий" рівень ізоляції — важливо вибрати той, який підходить для ваших потреб. Шопінговий додаток може працювати з Read Committed, але банківський додаток потребує Serializable. Ключовим є розуміння вимог вашого додатку та прийняття обґрунтованих компромісів.
Отже, наступного разу, коли ви будете налагоджувати проблему, пов’язану з транзакціями, приділіть хвилинку, щоб оцінити складність ізоляції — вона робить набагато більше для вас, ніж ви могли б подумати.
Перекладено з: Learning Databases? Don’t Overlook ACID Principles and Save Your Users’ Trust. Isolation