Savepoint (SQL)

Savepoint (от save point с англ. — «точка сохранения») — оператор языка SQL, который разделяет транзакцию на логические точки сохранения. Также это способ реализации субтранзакций (называемых вложенными транзакциями) в системе управления реляционными базами данных, путем указывания точки внутри транзакции, до которой транзакция может быть «откачена назад», не затрагивая какую-либо работу, выполненную в транзакции до точки сохранения.

В рамках одной транзакции могут существовать несколько точек сохранения. Они полезны для реализации комплексного восстановления ошибок в приложениях баз данных. Если во время транзакции с несколькими операциями возникает ошибка, приложение может восстановиться после ошибки (путем возврата к точке сохранения) без необходимости отменять всю транзакцию.

Поддерживаемые платформы:

Синтаксис SQL

править

Точку сохранения можно объявить следующим образом (при помощи оператора SAVEPOINT).

SAVEPOINT имя_точки_сохранения

В текущей транзакции устанавливается точка сохранения с именем 'имя_точки_сохранения'. Некоторые производители позволяют использовать в транзакции точки сохранения с одинаковыми именами, но стандарт ANSI так делать не рекомендует.

Все изменения, сделанные после объявления точки сохранения, могут быть отменены путем выдачи команды :

 ROLLBACK TO имя_точки_сохранения

Для удаления одной или нескольких точек сохранения используется команда:

 RELEASE SAVEPOINT имя_точки_сохранения

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

Как устроены точки сохранения

править

Точка сохранения (далее — ТС) представляет собой структуру данных, размещенную в динамической памяти сервера (в пуле транзакции) и имеющую уникальный числовой идентификатор. К каждой ТС привязан список действий, совершенных в её контексте (так называемый undo log или журнал отмены). В пределах транзакции ТС образуют стек и, следовательно, их откат всегда возможен только последовательно. Фрагменты журнала отмены распределены между ТС, которые инкрементно хранят историю всех изменений, выполненных в контексте транзакции.

Точка сохранения, активная на момент изменения какой-либо записи, называется текущей. Информация об изменении записи помещается в журнал отмены текущей ТС. В случае инициации отката до ТС журнал отмены раскручивается в обратную сторону, реконструируя запись к виду, в каком она существовала на момент установки данной ТС. После реконструкции всех изменённых записей ТС обычно удаляется из контекста транзакции. В случае отсутствия обработчиков исключений в контексте текущей ТС данный процесс может повторяться, отменяя изменения вышестоящих ТС. Помимо операции отката до ТС, существует ещё и операция штатного удаления (освобождения) ТС. В случае удаления ТС её журнал отмены объединяется с журналом отмены предыдущей в стеке ТС. С учётом вышесказанного можно говорить о вложенности ТС.

Советы и замечания по использованию

править

Точки сохранения устанавливаются в пределах транзакции, в которой они определены. Имена точек сохранения должны быть уникальными в пределах этой транзакции. Рекомендуется использовать инструкции BEGIN и COMMIT осторожно, поскольку, если вы случайно поставите инструкцию BEGIN слишком рано или COMMIT — слишком поздно, это может сильно повлиять на то, как транзакции будут записываться в базу данных. Рекомендуется выбирать человекопонятые имена точек, по скольку это увеличит читаемость кода. Повторное использование имени точки сохранения не приведет к ошибке или выводу предупреждения, а к тому, что предыдущая точка сохранения с таким именем окажется неработоспособной.

Пример

править

Для выполнения отката к точке сохранения после некоторых произведенных модификаций введите следующие команды:

INSERT INTO sales
VALUES (7896', 'JR3435', 'Oct 28 1997', 25, 'Net 60', 'BU7832');

SAVEPOINT after_insert;

UPDATE sales SET terms='Net 90'
WHERE sales_id='7896';

SAVEPOINT after_update;

DELETE sales;

ROLLBACK TO after_insert;

Как мы видим, именно команда ROLLBACK производит откат к точке сохранения с именем 'after_insert'.

Так же пример того, что мы можем создать несколько точек сохранения (в примере установлены две точки сохранения, к которым мы можем вернуться с помощью команды ROLLBACK):

UPDATE employees 
    SET salary = 7000 
    WHERE last_name = 'Banda';
SAVEPOINT banda_sal;

UPDATE employees 
    SET salary = 12000 
    WHERE last_name = 'Greene';
SAVEPOINT greene_sal;

SELECT SUM(salary) FROM employees;

ROLLBACK TO SAVEPOINT banda_sal;
 
UPDATE employees 
    SET salary = 11000 
    WHERE last_name = 'Greene';
 
COMMIT;

Пример удаления точки возврата (в примере наглядно показана работа команды RELEASE SAVEPOINT):

INSERT authors (au_id, au_lname, au_fname, contract)
VALUES ('111-11-1111', 'Rabbit', 'Jessica', 1);

SAVEPOINT first_savepoint;

INSERT authors (au_id, au_lname, au_fname, contract)
VALUES ('277-27-2777', 'Fudd', 'E.P.', 1);

SAVEPOINT second_savepoint;

INSERT authors (au_id, au_lname, au_fname, contract)
VALUES ('366-36-3636', 'Duck', 'P.J.', 1);

SAVEPOINT third_savepoint;

RELEASE SAVEPOINT second_savepoint;

COMMIT;

В этом примере при удалении точки сохранения second_savepoint система в действительности удаляет second_savepoint и third_savepoint, поскольку точка third_savepoint была создана после second_savepoint. После удаления точки сохранения её имя можно использовать снова.

Особенности команды SAVEPOINT

править

Указывает, что прикладная программа не может повторно использовать имя точки сохранения в блоке восстановления. Если в блоке восстановления уже существует точка сохранения с тем же именем, что и имя точки сохранения, то произойдет ошибка. Если опустить UNIQUE, это укажет на то, что приложение может повторно использовать имя точки сохранения в пределах единицы восстановления. Если svpt-название идентифицирует точку сохранения, которая уже существует в единице восстановления, а точка сохранения не была создана с помощью опции UNIQUE, существующая точка сохранения будет уничтожена и будет создана новая точка сохранения. Уничтожение точки сохранения для повторного использования своего имени — это не то же самое, что освобождение точки сохранения. Повторное использование имени точки сохранения уничтожает только одну точку сохранения. Освободить точку сохранения можно с помощью оператора RELEASE SAVEPOINT, будет произведено освобождение точки сохранения, а также всех точек сохранения, которые впоследствии были установлены.

ON ROLLBACK RETAIN CURSORS

править

Указывает, что все курсоры, которые открываются после сохранения точки сохранения не отслеживаются, и таким образом, не закрываются при откате в точку сохранения. Хотя эти курсоры остаются открытыми после отката в точку сохранения, они могут не использоваться. Например, если откат назад к точке сохранения вызывает вставку строки, на которую курсор помещается для отката, то использование курсора для обновления или удаления строки приводит к ошибке.

ON ROLLBACK RETAIN LOCKS

править

Указывает, что любые блокировки, которые были получены после сохранения точки сохранения не отслеживаются, и таким образом, не отбрасываются при откате в точку сохранения. ON ROLLBACK RETAIN LOCKS — это поведение по умолчанию.

Литература

править
  • Gunderloy, M.; Jorden, J.L.; Tschanz, D.W. Mastering Microsoft SQL Server 2005. — Wiley, 2006. — P. 200-201. — ISBN 9780471792239.
  • Darie, C. and Watson, K. The Programmer's Guide to SQL. — Apress, 2008. — P. 271—274. — ISBN 9781430208006.
  • Alapati, S. Expert Oracle Database 11g Administration. — Apress, 2009. — P. 338-339. — ISBN 9781430210160.

Ссылки

править
  • [1], Database SQL Reference, Oracle
  • [2], DB2 SQL, IBM