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