Savepoint (SQL)
Savepoint (от save point с англ. — «точка сохранения») — оператор языка SQL, который разделяет транзакцию на логические точки сохранения. Также это способ реализации субтранзакций (называемых вложенными транзакциями) в системе управления реляционными базами данных, путем указывания точки внутри транзакции, до которой транзакция может быть «откачена назад», не затрагивая какую-либо работу, выполненную в транзакции до точки сохранения.
В рамках одной транзакции могут существовать несколько точек сохранения. Они полезны для реализации комплексного восстановления ошибок в приложениях баз данных. Если во время транзакции с несколькими операциями возникает ошибка, приложение может восстановиться после ошибки (путем возврата к точке сохранения) без необходимости отменять всю транзакцию.
Поддерживаемые платформы:
- DB2
- Oracle
- SQL Server (используется команда SAVE)
- SQL Base
- MySQL
- SQLite (начиная с версии 3.6.8)
- PostgreSQL
- и другие
Синтаксис 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
[править | править код]Указывает, что прикладная программа не может повторно использовать имя точки сохранения в блоке восстановления. Если в блоке восстановления уже существует точка сохранения с тем же именем, что и имя точки сохранения, то произойдет ошибка. Если опустить 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.
Ссылки
[править | править код]Для улучшения этой статьи желательно:
|