Получи случайную криптовалюту за регистрацию!

​​ Команды управления транзакциями (SAVEPOINT). Мы с вами уж | Postgres Guru | Базы данных

​​ Команды управления транзакциями (SAVEPOINT).

Мы с вами уже познакомились с основными командами управления транзакциями в PostgreSQL. И знаем, что если внутри транзакции случится какая-то ошибка, то все удачно завершившиеся запросы в рамках этой транзакции откатятся назад.

Вот пример:

BEGIN; - начали транзакцию

CREATE TABLE test(id int); - создали таблицу test

SELECT * FROM does_not_exist_table; - здесь мы намерено обратились к несуществующей таблице, чтобы вызвать ошибку

ERROR: relation "does_not_exist_table" does not exist - получили ошибку

Дальше какие бы мы команды не вводили, они будут проигнорированы, так как у нас ошибка и нам надо откатить транзакцию.

ERROR: current transaction is aborted, commands ignored until end of transaction

ROLLBACK; - откатываем транзакцию

Теперь, если мы попробуем обратиться к таблице text, то мы ее не найдём, так как изменения не применились.

\d test

Did not find any relation named "test".

Но что если нам надо в целях отладки какого-нибудь запроса не откатывать все изменения в транзакции? Если мы не хотим потерять какие то данные в случае ошибки в транзакции?

В этом случае нам поможет команда SAVEPOINT. Т.е. точка сохранения. Когда мы внутри транзакции укажем точку сохранения, то транзакция в случае ошибки откатиться до этой точки.

Пример:

BEGIN; - начинаем транзакцию

CREATE TABLE test(id int); - создаем таблицу

INSERT INTO test VALUES (1); - вставляем значение в таблицу

SAVEPOINT my_point; - делаем точку сохранения. Ей нужно присвоить какое-то имя.

INSERT INTO test values (2); - вставляем еще значение в таблицу

INSERT INTO does_not_exist values (1); - вызываем ошибку, вставляя значение в несуществующую таблицу

ERROR: relation "does_not_exist" does not exist

LINE 1: insert into does_not_exist values (1);

ERROR: current transaction is aborted, commands ignored until end of transaction block

ROLLBACK to my_point; - откатываем транзакцию к точке сохранения

Теперь если мы сделаем запрос к таблице test:

SELECT * FROM test;

то увидим следующий результат:

id
---
 1
(1)

Как видно из результата, у нас осталась таблица test и первое значение. Т.е. то, что мы сделали до точки сохранения. Все остальные изменения откатились.

#queries