У PostgreSQL НЕМАЄ справжніх вкладених транзакцій у стандартному розумінні цього терміну. Є тільки зовнішня транзакція і "шари" точок збереження всередині неї.
Термін "вкладені транзакції" в PostgreSQL зазвичай означає використання точок збереження (savepoints) через команди SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT. Це не окремі незалежні транзакції, а спеціальні контрольні точки всередині однієї зовнішньої транзакції, до яких можна відкотитися, не відкочуючи всю транзакцію повністю.
Приклад з життя: ти пишеш великий текст у редакторі і час від часу тиснеш ctrl+s. Якщо накосячив, можна відкотитися до однієї з попередніх збережених версій, не втрачаючи весь прогрес.
Команди для керування точками збереження
Для керування вкладеними транзакціями PostgreSQL дає три основні команди:
SAVEPOINT
Ця команда використовується для створення "точок збереження", до яких можна відкотитися при потребі. Така точка працює як контрольний пункт у нашій транзакції.
SAVEPOINT mypoint;
ROLLBACK TO SAVEPOINT
Відкочує частину змін, зроблених після вказаної точки, залишаючи недоторканими більш ранні зміни в межах тієї ж зовнішньої транзакції.
ROLLBACK TO SAVEPOINT mypoint;
RELEASE SAVEPOINT
Видаляє точку збереження. Після цього до неї вже не можна відкотитися.
RELEASE SAVEPOINT mypoint;
Приклад: додавання даних у кілька таблиць з можливістю відкату
Уяви, ти працюєш над системою керування замовленнями, де треба зберегти дані одразу у дві таблиці: orders і order_items. Помилка при додаванні в одну таблицю не повинна призводити до відкату даних з іншої.
BEGIN; -- Початок транзакції
-- Створюємо точку збереження
SAVEPOINT before_order;
-- Додаємо замовлення в таблицю orders
INSERT INTO orders (order_id, customer_id, date)
VALUES (1, 101, CURRENT_DATE);
-- Якщо тут виникає помилка — відкочуємось
SAVEPOINT before_order_items;
-- Додаємо товари в таблицю order_items
INSERT INTO order_items (order_id, product_id, quantity)
VALUES (1, 2001, 4);
-- Якщо щось пішло не так
-- ROLLBACK TO SAVEPOINT before_order_items;
-- Підтверджуємо транзакцію (фіксуємо зміни)
COMMIT;
Якщо на етапі додавання записів у order_items виникне помилка, можна відкотитися до точки before_order_items, а зміни в таблиці orders залишаться.
Практичні поради та типові помилки
Тепер, коли ти розумієш, як працюють команди SAVEPOINT і ROLLBACK TO SAVEPOINT, ось кілька рекомендацій, щоб уникнути проблем:
- Назви точок збереження. Використовуй зрозумілі й унікальні імена для
SAVEPOINT. Наприклад,before_insert,step1і так далі — це допоможе орієнтуватися під час дебагу. - Не забувай відпускати
SAVEPOINT. Якщо ти більше не плануєш повертатися до точки, видаляй її черезRELEASE SAVEPOINT, щоб не захаращувати транзакцію. - Вкладена транзакція ≠ окрема транзакція. Пам’ятай, що при виклику команди
COMMITвсі точки збереження зникають. Якщо зовнішнійCOMMITвиконано, відкотитися вже не вийде. - Блокування даних. Навіть якщо ти відкотився до точки, блокування записів, встановлені в рамках транзакції, залишаються. Це важливо враховувати при роботі у багатокористувацькому середовищі.
Вкладені транзакції з використанням SAVEPOINT і ROLLBACK TO SAVEPOINT дають розробникам потужний інструмент для обробки складних ситуацій. Тепер ти можеш розбивати транзакції на гнучкі етапи, акуратно обробляти помилки й уникати зайвого відкату даних. Пам’ятай, що кожного разу, коли бачиш слово "відкат", це не завжди привід для паніки: іноді відкотити — найкращий спосіб рухатися вперед.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ