4.9.Транзакціі, блокування і розрахований на багато користувачів доступ до даних.
Будь-яка база даних придатна до використання тільки тоді, коли її стан відповідає стану предметної області. Такі стани називають цілісними. Очевидно, що при зміні даних БД повинна переходити від одного цілісного стану до іншого. Однак, в процесі оновлення даних можливі ситуації, коли стан цілісності порушується. наприклад:- У банківській системі здійснюється переказ грошових коштів з одного рахунку на інший. Мовою SQL ця операція описується послідовністю двох команд UPDATE. Як бачимо, після виконання першої команди і до завершення другої команди база даних не знаходиться в цілісному стані (шукана сума списана з першого рахунку, але не зарахована на другий). Якщо в цей момент в системі відбудеться збій (наприклад, виключення електроживлення), то цілісний стан БД буде безповоротно втрачено.
- Цілісність БД може порушуватися і під час обробки однієї команди SQL. Нехай виконується операція збільшення зарплати всіх співробітників фірми на 20%: При цьому СУБД послідовно обробляє всі записи, що підлягають оновленню, тобто існує часовий інтервал, коли частина записів містить нові значення, а частина - старі.
Щоб уникнути таких ситуацій в СУБД вводиться поняття транзакції - атомарного дії над БД, який переводить її з одного цілісного стану в інший цілісний стан. Іншими словами, транзакція - це послідовність операцій, які повинні бути або всі виконані або все не виконані (все або нічого).
Методом контролю за транзакціями є ведення журналу. в якому фіксуються всі зміни, що здійснюються транзакцією в БД. Якщо під час обробки транзакції відбувається збій, транзакція відкочується - з журналу восстанавліваеться стан БД на момент початку транзакції.
В СУБД різних постачальників початок транзакції може здаватися явно (наприклад, командою BEGIN TRANSACTION), або матися на увазі неявним (так визначено в стандарті SQL), тобто чергова транзакція відкривається автоматично одразу ж після вдалого або невдалого завершення попередньої. Для завершення транзакції зазвичай використовують команди SQL:- COMMIT - успішно завершити транзакцію
- ROLLBACK - відкотити транзакцію, тобто повернути БД в стан, в якому вона перебувала на момент початку транзакції.
- оператор COMMIT означає успішне завершення транзакції, всі зміни, внесення в базу даних робляться постійними
- оператор ROLLBACK перериває транзакцію і скасовує всі внесені нею зміни
- успішне заверешення програми, яка ініціювала транзакцію, означає успішне завершення транзакції (як використання COMMIT)
- помилкове завершення програми перериває транзакцію (як ROLLBACK)
- Брудне читання (Dirty Read) - транзакція Т1 модифікувала якийсь елемент даних. Після цього інша транзакція Т2 прочитала вміст цього елементу даних до завершення транзакції Т1. Якщо Т1 заврешается операцією ROLLBACK. то виходить, що транзакція Т2 прочитала неіснуючі дані.
- Є повторюваною (розмите) читання (Non-repeatable or Fuzzy Read) - транзакція Т1 прочитала вміст елемента даних. Після цього інша транзакція Т2 модифікувала або видалила цей елемент. Якщо Т1 прочитає вміст цього елементу занова, то вона отримає інше значення або виявить, що елемент даних більше не існує.
- Фантом (фіктивні елементи) (Phantom) - транзакція Т1 прочитала вміст кількох елементів даних, що задовольняють нікому умові. Після цього Т2 створила елемент даних, що задовольняє цій умові і зафіксувалася. Якщо Т1 повторить читання з тим же умовою, вона отримає інший набір даних.
Всі описані вище ситуації виникли тільки тому, що чергується виконання транзакцій Т1 і Т2 не було впорядковано, тобто не було еквівалентно виконанню спочатку транзакції Т1, а потім Т2, або, навпаки, спочатку транзакції Т2, а потім Т1.
Примусове впорядкування транзакцій забезпечується за допомогою механізму блокувань. Суть цього механізму в наступному: якщо для виконання деякої транзакції необхідно, щоб деякий об'єкт бази даних (кортеж, набір кортежів, ставлення, набір відносин.) Не змінився непередбачувано і без відома цієї транзакції, такий об'єкт блокується. Основними видами блокувань є:- блокування з взаємним доступом. звана також S-блокуванням (від Shared locks) і блокуванням з читання.
- монопольна блокування (без взаємного доступу), що також називається X-блокуванням від (eXclusive locks) або блокуванням по запису. Цей режим використовується при операціях зміни, додавання і видалення об'єктів.
- якщо транзакція накладає на об'єкт X-блокування, то будь-який запит іншої транзакції з блокуванням цього об'єкта буде відкинутий.
- якщо транзакція накладає на об'єкт S-блокування, то
- запит з боку іншої транзакції з X-блокувань на цей об'єкт буде відкинутий
- запит з боку іншої транзакції з S-блокувань цього об'єкта буде прийнятий
Доведено, що серіалізуемость транзакцій (або, інакше, їх ізоляція) забезпечується при використанні двофазного протоколу блокувань (2LP - Two-Phase Locks), згідно з яким всі блокування, вироблені транзакцією, знімаються тільки при її завершенні. Тобто Виконання покрівельних транзакції розбивається на дві фази: (1) - накопичення блокувань, (2) - звільнення блокувань в результаті фіксації або відкоту.
На жаль, застосування механізму блокування призводить до уповільнення обробки транзакцій, оскільки система змушена очікувати поки звільняться дані, захоплені конкуруючої транзакцією. Вирішити цю проблему можна за рахунок зменшення фрагментів даних, що захоплюються транзакцією. Залежно від захоплюваних об'єктів розрізняють кілька рівнів блокування.- блокується вся база даних - очевидно, цей варіант неприйнятний, оскільки зводить розрахований на багато користувачів режим роботи до розрахованого на одного користувача
- блокуються окремі таблиці
- блокуються сторінки (сторінка - фрагмент таблиці розміром зазвичай 2-4 Кб, одиниця виділення пам'яті для обробки даних системою)
- блокуються записи
- блокуються окремі поля
Мова SQL також надає спосіб непрямого управління швидкістю виконанню транзакцій за допомогою вказівки рівня ізоляції транзакції. Під рівнем ізоляції транзакції розуміється можливість виникнення однієї з описаних вище помилкових ситуацій. У стандарті SQL визначені 4 рівні ізоляції: