Транзакція (бази даних)

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до: навігація, пошук

Транза́кція (англ. transaction) — група послідовних операцій з базою даних, яка є логічною одиницею роботи з даними. Транзакція може бути виконана або цілком і успішно, дотримуючись цілістності даних і незалежно від інших транзакцій, що йдуть паралельно, або не виконана зовсім, і тоді вона не може справити ніякого ефекту. Транзакції оброблюються транзакційними системами, в процесі роботи яких створюється історія транзакцій.

Розрізняють послідовні (звичайні), паралельні и розподілені транзакції. Розподілені транзакції вбачають використання більш ніж однієї транзакційної системи и потребують набагато більш складної логіки (наприклад, two-phase commit — двофазний протокол фіксації транзакції). Також, в деяких системах реалізовані автономні транзакції, або під-транзакції, які є автономною частиною батьківської транзакції.

Приклад транзакції[ред.ред. код]

Приклад: необхідно переказати с банківського рахунку номер 5 на рахунок номер 7 суму в 10 грошових одиниць. Цього можна досягти, наприклад, наведеною послідовністю дій:

  • Почати транзакцію
прочитати баланс на рахунку номер 5
зменшити баланс на 10 грошових одиниць
зберегти новий баланс рахунку номер 5
прочитати баланс на рахунку номер 7
збільшити баланс на 10 грошових одиниць
зберегти новий баланс рахунку номер 7
  • Закінчити транзакцію

Ці дії являють собою логічну одиницю роботи «переказ суми між рахунками», і, таким чином, є транзакцією. Якщо перервати дану транзакцію, наприклад, в середині, и не анулювати всі зміни, легко залишити власника рахунка номер 5 без 10 одиниць, тоді як власник рахунка номер 7 їх не отримає.

Властивості транзакцій[ред.ред. код]

Одним з найбільш розповсюджених наборів вимог до транзакцій і транзакцінних сист ем є набір ACID (Atomicity, Consistency, Isolation, Durability). Вимоги ACID були в головному сформульовані в кінці 70-х років Джимом Греєм[1]. Разом з тим, існують специалізовані системи с ослабленими транзакційними властивостями[2].

Atomicity — Атомарність[ред.ред. код]

Докладніше: Атомарність

Атомарність гарантує, що ніяка транзакція не буде зафіксована в системі частково. Будуть або виконані всі її підоперації, або не виконано жодної. Оскільки на практиці неможливо одночасно і атомарно виконати всю послідовність операцій усередині транзакції, вводиться поняття «відката» (rollback): якщо транзакцію не вдається повністю завершити, результати всіх її до сих пір виконаних дій будуть відмінені, і система повернеться до стану на початок транзакції.

Consistency — Узгодженість[ред.ред. код]

Одна з найскладніших і неоднозначних властивостей з четвірки ACID. У відповідності до цієї вимоги, система знаходиться в узгодженому стані до початку транзакції і повинна залишитись в узгодженому стані після завершення транзакції. Не можна плутати вимогу узгодженості з вимогами цілістності (integrity). Останні правила є більш вузькими і, багато в чому, спеціфічні для реляційних СКБД: є вимоги цілістності типів (domain integrity), цілістності посилань (referential integrity), цілістності сутностей (entity integrity), які не можуть бути порушені фізично в силу особливостей реалізації системи.

Узгодженість є більш широким поняттям. Наприклад, в банківській системі може існувати вимога рівності суми, що списується з одного рахунка, сумі, що зачислюється на інший. Це бізнес-правило і воно не може бути гарантовано тільки перевірками цілістності, його повинні дотриматись програмісти при написанні коду транзакцій. Якщо будь-яка транзакція виконає списання, але не виконає зачислення, то система залишиться в некоректному стані і властивість узгодженості буде порушена.

Нарешті, ще одне зауваження стосується того, що під час виконання транзакції узгодженість не потребується. В нашому прикладі, списання і зачислення будуть, скоріш за все, двома різними підопераціями и між їх виконанням всередині транзакції буде видно неузгоджений стан системи. Однак не треба забувати, що при виконанні вимоги ізоляції, жодним іншим транзакціям ця неузгодженість не буде видна. А атомарність гарантує, що транзакція або буде повністю завершена, або жодна з операцій транзакції не буде виконана. Тим самим ця проміжна неузгодженість є прихованою.

Isolation — Ізольованість[ред.ред. код]

Шаблон:См. також Під час виконания транзакції паралельні транзакції не повинні впливати на її результат. Ця властивість не дотримується на рівні ізольованості Repeatable Read та нижче.

Durability — надійність[ред.ред. код]

Незалежно від проблем на нижніх рівнях (наприклад, при знеструмленні системи чи збоях в обладнанні), зміни, зроблені транзакцією, яка успішно завершена, повинні залишитись збереженими після повернення системи до роботи. Іншими словами, якщо користувач отримав підтверждення від системи, що транзакція виконана, він може бути впевнений, що зміни, які він зробив, не будуть відмінені через будь-який збій.

Рівні ізоляції транзакцій[ред.ред. код]

В ідеалі транзакції різних користувачів повинні виконуватись так, щоб створювалась ілюзія, що користувач поточної транзакції — єдиний. Однак в реальності, з міркувань продуктивності і для виконания деяких спеціальних задач, СКБД забезпечують певні рівні ізоляції транзакцій.

Рівні є описаними в порядку збільшення ізольованості транзакцій і, відповідно, надійності роботи з даними.

  • 0 — Читання непідтверждених даних (брудне читання) (Read Uncommitted, Dirty Read) — читання незафіксованих змін як своєї транзакції, так і паралельних транзакцій. Немає гарантії, що дані, змінені іншими транзакціями, не будуть в будь-який момент змінені в результаті їх відката, тому таке читання є потенційним джерелом помилок. Неможливими є втрачені зміни (lost changes), можливими є неповторювані читання і фантоми.
  • 1 — Читання підтверждених даних (Read Committed) — читання всіх змін своєї транзакції і зафіксованих змін паралельних транзакцій. Втрачені зміни и брудне читання не дозволяються, можливими є неповторюване читання і фантоми.
  • 2 — Повторюване читання (Repeatable Read, Snapshot) — читання всіх змін своєї транзакції, будь-які зміни, внесені паралельними транзакціями після початку своєї, є недоступними. Втрачені зміни, брудне и неповторюване читання є неможливими, можливі фантоми.
  • 3 — Впорядкований — (Serializable) — впорядковані транзакції. Результат паралельного виконания впорядкованої транзакції з іншими транзакціями повинен бути логічно еквівалентен результату їх будь-якого послідовного виконання. Проблеми сінхронізації не виникають.

Чим вище рівень ізоляції, тим більше потребується ресурсів, щоб його забеспечити. Відповідно, підвищення ізольованості може приводити до зниження швидкості виконання паралельних транзакцій, що є «платою» за підвищення надійності.

В СУБД рівень ізоляції транзакцій можна вибрати як для всіх транзакцій разом, так і для одної конкретної транзакції. За замовчуванням в більшості баз даних використовується рівень 1 (Read Committed). Рівень 0 використовується в основному для відстеження змін тривалих транзакцій або для читання даних, що рідко змінюються. Рівні 2 и 3 використовуються при підвищених вимогах до ізольованості транзакцій.

Реалізація[ред.ред. код]

Повноцінна реалізація рівнів ізоляції і властивостей ACID є нетривіальною задачею. Обробка вхідних даних приводить до великої кількості маленьких змін, включаючи обновлення як самих таблиць, так і індексів. Ці зміни потенційно можуть потерпіти поразку: закінчилось місце на диску, операція займає забагато часу (timeout) і т. д. Система повинна у випадку невдачі коректно повернути базу даних у стан до транзакції.

Перші комерційні СКБД (наприклад, IBM DB2), користались виключно блокуванням доступу до даних для забеспечення властивостей ACID. Але велика кількість блокувань приводить до суттєвого зменшення продуктивності. Є два популярних семейства розв’язків цієї проблеми, які знижують кількість блокувань:

В обох випадках, блокування повинні бути розставлені на всю інформацію, яка обновлюється. В залежності від рівня ізоляції і імплементації, блокування записів також розставляються на інформацию, яка була прочитана транзакцією.

При упереджуючій журнализації, яка використовується в Sybase і MS SQL Server до версії 2005, всі зміни записуються до журналу, і тільки після успішного завершення - до бази даних. Це дозволяє СКБД повернутись до робочого стану після нечеканого падіння системи. Тіньові сторінки містять копії тих сторінок бази даних на початок транзакції, в яких трапляються зміни. Ці копії активуються після успішного завершення. Хоча тіньові сторінки легше реалізуються, упереджуюча журналізація більш ефективна[4]

Подальший розвиток технологій керування базами даних привів до появи безблоковних технологій. Ідея контроля за паралельним доступом з допомогою часових міток (timestamp-based concurrency control) була розвинена і привела до появи багатоверсійної архитектури MVCC. Ці технології не потребують ні журнализації змін, аніж тіньових сторінок. Архітектура, що реалізована в Oracle 7.х і вище, записує старі версії сторінок в спеціальний сегмент відкату, але вони все ще доступні для читання. Якщо транзакція при читанні попадає на сторінку, часова мітка якої новіше за початок читання, дані беруться з сегменту відката (тобто використовується «стара» версія). Для підтримки такої роботи ведеться журнал транзакцій, але на відмінність від «упереджуючої журналізації», він не містить даних. Робота з ним складається з трьох логічних шагів:

  1. Записати намір провести деякі операції
  2. Виконати завдання, копіюючи оригінали сторінок, що змінюються, до сегменту відката
  3. Записати, що все зроблено без помилок

Журнал транзакцій в комбінації з сегментом відката (область, в якій зберігається копія всіх даних, що змінюються в ході транзакції) гарантує цілістність даних. У випадку збоя запускається процедура відновлення, яка продивляє окремі його записи наступним чином:

  • Якщо запис є пошкодженим, то збій трапився під час проставлення відмітки в журналі. Значить, ничого важливого не загубилось, ігноруємо цю помилку.
  • Якщо всі записи помічені як успішно виконані, то збій трапився між транзакціями, тут також немає втрат.
  • Якщо в журналі є незакінчена транзакція, то збій трапився під час запису на диск. У цьому випадку ми відновлюємо стару версію даних з сегменту відката.

Firebird взагалі не має ні журнала змін, ані сегменту отката, а реалізує MVCC, записуючи нові версії рядків таблиць прямо до активного простору даних. Так же робить MS SQL 2005. Теоретично це дає максимальну ефективность при паралельній роботі з даними, але ціною є необхідність «збирання мусора», тобто видалення старих и вже не потрібних версій даних.

См. також[ред.ред. код]

Примітки[ред.ред. код]

  1. Gray, Jim. The Transaction Concept: Virtues and Limitations. Proceedings of the 7th International Conference on Very Large Databases: pages 144—154, 1981(англ.)
  2. Advanced Transaction Models and Architectures(англ.)
  3. Семейство алгоритмов ARIES
  4. Gray, J., McJones, P., Blasgen, M., Lindsay, B., Lorie, R., Price, T., Putzolu, F., and Traiger, I. The recovery manager of the System R database manager. ACM Comput. Surv. 13, 2 (June 1981).

Шаблон:Databases