На нашому курсі ми будемо розглядати транзакції тричі. І кожного разу будемо відкривати для себе щось новеньке. Зараз ми вивчимо основи транзакцій. А вже в другій половині курсу розберемося з рівнями ізоляції транзакцій, а в самому кінці — нюанси роботи вкладених транзакцій.
Що таке транзакція
Почнемо з простого — визначення. Транзакція — це група дій, які виконуються тільки разом. Все.
З цього випливає важливий висновок: якщо при виконанні якоїсь (будь-якої!) дії групи стався збій, то треба відкотити результат роботи всіх інших дій і повернути систему в початковий стан.
З точки зору SQL, транзакція — це набір дій (наприклад, вставка, оновлення або видалення даних), яка гарантує, що або всі операції всередині транзакції успішно завершаться, або жодна з них не буде виконана. Таке поводження робить роботу з базами даних надійною і узгодженою, особливо в критичних сценаріях, як-от обробка платежів чи оновлення пов’язаних даних.
Уяви, що ти переводиш гроші між двома банківськими рахунками. Якщо спростити, у нас є дві послідовні операції:
- З одного рахунку списується сума.
- На інший рахунок зараховується та ж сума.
Якщо станеться збій в самому кінці операції (наприклад, впаде сервер), важливо, щоб жоден з користувачів не залишився в мінусі. Іншими словами, або обидва кроки успішні (транзакція фіксується), або обидва кроки відкочуються (транзакція скасовується).
Транзакції та принципи ACID
Транзакції базуються на принципах ACID, які нагадують нам про чотири ключові характеристики:
- Atomicity (Атомарність): все або нічого. Або всі операції всередині транзакції виконуються, або відкочуються.
- Consistency (Узгодженість): дані залишаються в коректному стані до і після транзакції.
- Isolation (Ізоляція): кожна транзакція працює так, ніби вона єдина в системі.
- Durability (Довговічність): після фіксації дані зберігаються, навіть якщо сервер впаде.
Основні команди для керування транзакціями
Тепер готуйся до практики! Ось три головні команди для керування транзакціями:
BEGIN
Починає нову транзакцію. Всі наступні операції будуть виконуватись в її рамках.COMMIT
Фіксує зміни. Після виконання цієї команди всі дії стають постійними.ROLLBACK
Скасовує зміни. Якщо щось пішло не так, можна відкотити транзакцію, і дані залишаться в початковому стані.
Базовий синтаксис транзакцій
Проста структура транзакції:
BEGIN;
-- тут йдуть твої SQL-операції
COMMIT;
Приклад використання ROLLBACK:
BEGIN;
-- зміна таблиці students
UPDATE students
SET grade = grade + 10
WHERE id = 1;
-- О! Ми зрозуміли, що це була помилка.
ROLLBACK;
Приклад використання транзакції в реальному завданні
Припустимо, у нас є таблиці:
students:
| id | name | grade |
|---|---|---|
| 1 | Otto Lin | 85 |
| 2 | Anna Song | 90 |
courses:
| course_id | course_name |
|---|---|
| 1 | Математика |
| 2 | Історія |
Допустимо, ми хочемо одночасно записати студента на курс і оновити його середній бал:
BEGIN;
-- Крок 1: Додаємо запис у таблицю "записи на курси"
INSERT INTO course_enrollments (student_id, course_id)
VALUES (1, 2);
-- Крок 2: Оновлюємо середній бал студента
UPDATE students
SET grade = grade + 5
WHERE id = 1;
COMMIT;
Що буде, якщо впаде сервер між першим і другим кроком? Якби ми не використовували транзакцію, дані були б у неузгодженому стані: запис на курс додасться, а середній бал не оновиться. Але з транзакцією обидві операції або виконуються, або обидві скасовуються.
Робота з помилками всередині транзакцій
Іноді щось іде не так, і треба грамотно обробити помилку. У PostgreSQL транзакція автоматично відкочується, якщо станеться помилка.
Давай помилимося спеціально і подивимось, що буде. Уяви, що у нас є обмеження на унікальність стовпця student_id у таблиці course_enrollments. Давай спробуємо додати дубльований рядок:
BEGIN;
INSERT INTO course_enrollments (student_id, course_id)
VALUES (1, 2);
-- КІНЕЦЬ ТРАНЗАКЦІЇ (поки не виконано)
COMMIT;
Якщо вставити студента, який вже записаний на курс, станеться помилка, і PostgreSQL автоматично завершить транзакцію з відкотом.
Використання ROLLBACK для ручного відкату
Часто помилки передбачити неможливо, і ти захочеш відкотити транзакцію, якщо щось піде не так:
BEGIN;
-- Додаємо нового студента
INSERT INTO students (name, grade)
VALUES ('Omori Sanny', 75);
-- Оп! Ми зрозуміли, що студента додали випадково.
ROLLBACK;
Після команди ROLLBACK таблиця залишається незмінною — Omori Sanny так і не з’явився в students.
Корисні поради та типові помилки
Працювати з транзакціями простіше, якщо пам’ятати кілька важливих правил:
- Завжди використовуй транзакції, якщо твоя операція включає більше одного кроку, особливо при зміні даних у кількох таблицях.
- Ніколи не забувай фіксувати зміни (
COMMIT). Інакше транзакція залишиться незавершеною, а дані не зміняться. - Обгортай складні операції в транзакції для збереження узгодженості даних.
- Якщо бачиш помилку на будь-якому етапі, не бійся використовувати
ROLLBACK.
Тепер, коли ти знаєш, як контролювати операції за допомогою транзакцій, саме час застосувати ці знання на практиці й перейти до вивчення транзакцій для забезпечення цілісності даних!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ