Savepoint (SQL)

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

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

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

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

Синтаксис SQL[править | править код]

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

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

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

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

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

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

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

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

Как устроены Savepoints (точки сохранения)[править | править код]

Точка сохранения (далее — ТС) представляет собой структуру данных, размещенную в динамической памяти сервера (в пуле транзакции) и имеющую уникальный числовой идентификатор. К каждой ТС привязан список действий, совершенных в её контексте (так называемый 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 — это поведение по умолчанию.

Литература[править | править код]

Ссылки[править | править код]

  • [1], Database SQL Reference, Oracle
  • [2], DB2 SQL, IBM