JavaRush /Курси /SQL SELF /Заглиблюємось у транзакції

Заглиблюємось у транзакції

SQL SELF
Рівень 39 , Лекція 0
Відкрита

Ми вже згадували раніше в курсі, що таке транзакція. Нагадаю, це — послідовність операцій, яка має виконуватись як єдине ціле. Ну от якщо треба зробити банківський переказ. У такому випадку ми знімаємо гроші з одного рахунку і зараховуємо їх на інший. Якщо одне з цих дій не вдасться (наприклад, гроші списались, але не зарахувались), це створить купу проблем. Саме тут транзакції приходять на допомогу.

Транзакція або виконається повністю, або не виконається взагалі. Це називається принципом "все або нічого".

BEGIN;
-- Зменшуємо баланс на одному рахунку
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- Збільшуємо баланс на іншому рахунку
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT; -- Застосовуємо зміни

Якщо щось піде не так, можна відкотити зміни за допомогою ROLLBACK.

Що таке ACID-властивості транзакцій

Коли ми говоримо про транзакції в PostgreSQL (і взагалі в реляційних базах даних), часто згадується абревіатура ACID — це не про хімію. ACID розшифровується як Atomicity (атомарність), Consistency (узгодженість), Isolation (ізоляція), Durability (надійність). Ці чотири властивості забезпечують, щоб дані оброблялись безпечно, послідовно і без сюрпризів.

Атомарність (Atomicity)
Транзакція виконується цілком або не виконується взагалі. Якщо всередині неї щось пішло не так — все відкочується. Уяви: ти переводиш гроші, і раптом помилка — або все скасовується, або переказ відбувається повністю. Ніяких "наполовину" операцій.

Узгодженість (Consistency)
Після завершення транзакції база залишається у коректному, логічному стані. Всі правила, обмеження і зв’язки між таблицями мають дотримуватись. Наприклад, якщо у тебе заборонено від’ємний баланс, транзакція з порушенням просто не буде збережена.

Ізоляція (Isolation)
Поки одна транзакція не завершилась, інша не повинна бачити її проміжні дані. Це захист від дивних ефектів, коли ти бачиш «невизначений» стан даних. Уяви, що в інтернет-магазині гроші вже списали, а товар ще не додали в замовлення — не дуже приємно, правда?

Надійність (Durability)
Якщо транзакція завершилась успішно, всі її зміни гарантовано зберігаються. Навіть якщо одразу після цього вимкнули світло — дані залишаться в базі. Це як натиснути "Зберегти" і бути впевненим, що все точно на місці.

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

Приклади сценаріїв застосування транзакцій

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

Ось кілька типових прикладів, де транзакції реально рятують ситуацію:

1. Обробка платежів

Коли клієнт переводить гроші з одного рахунку на інший, транзакція гарантує, що гроші не зникнуть ні туди, ні сюди:

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT;

Якщо на першому рахунку недостатньо коштів, можна відкотити зміни:

BEGIN;
UPDATE accounts SET balance = balance - 500 WHERE account_id = 1;
-- Ой, баланс від’ємний!
ROLLBACK;

2. Оновлення пов’язаних таблиць

Уяви, що ти оновлюєш статус студента на "випущений" і одночасно додаєш запис у таблицю "випускники":

BEGIN;
UPDATE students SET status = 'graduated' WHERE student_id = 42;
INSERT INTO graduates (student_id, graduation_date) VALUES (42, '2023-06-10');
COMMIT;

Якщо одна з операцій не вдалася (наприклад, сталася помилка в INSERT), база даних поверне початковий стан.

3. Масове оновлення даних

Транзакції корисні для виконання великих оновлень, наприклад:

BEGIN;
UPDATE orders SET status = 'completed' WHERE delivery_date < CURRENT_DATE;
COMMIT;

Якщо сервер впав або ти помітив, що оновлення пішло не туди, ти можеш відкотити зміни у будь-який момент!

Команди для роботи з транзакціями

PostgreSQL надає кілька ключових команд:

  • BEGIN: починає нову транзакцію:

    BEGIN;
    
  • COMMIT: фіксує (зберігає) всі зміни, зроблені в рамках транзакції:

    COMMIT;
    

ROLLBACK: відкочує всі зміни, зроблені в поточній транзакції:

ROLLBACK;

Приклад повного циклу

BEGIN;
-- Деякі операції
UPDATE accounts SET balance = balance - 200 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 200 WHERE account_id = 2;

-- Вирішили відкотити зміни
ROLLBACK;

-- Починаємо знову
BEGIN;
-- Ті ж операції, але інший переказ
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;

-- Завершуємо транзакцію
COMMIT;

Життя транзакцій поза підручником

Інтернет-магазини. Багато платформ використовують транзакції для керування замовленнями і платежами. Наприклад, замовлення виконується тільки у разі успішної оплати. Якщо щось пішло не так, замовлення автоматично скасовується.

Банківські системи. Транзакції захищають твої гроші від проблем типу несподіваного вимкнення світла.

Історія транзакцій. PostgreSQL зберігає журнали WAL (Write-Ahead Logging) для відновлення даних у разі збою. Це магія, яка робить транзакції надійними.

У наступній лекції ми розберемо команди BEGIN, COMMIT і ROLLBACK детальніше, а також подивимось на приклади масових операцій і часткових відкотів з SAVEPOINT. До зустрічі!

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ