Savepoint (SQL): различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
[отпатрулированная версия][непроверенная версия]
Содержимое удалено Содержимое добавлено
Советы и замечания по использованию: надо убрать инструкцию, удалять раздел у меня рука не поднимается, а переписывать лень
переработка раздела советов
Метки: через визуальный редактор с мобильного устройства из мобильной версии через расширенный мобильный режим Задача для новичков Задача для новичков: корректура
Строка 31: Строка 31:


== Советы и замечания по использованию ==
== Советы и замечания по использованию ==
Точки сохранения устанавливаются в пределах транзакции, в которой они определены. Имена точек сохранения должны быть уникальными в пределах этой транзакции. Рекомендуется использовать инструкции [[BEGIN]] и [[COMMIT]] осторожно, поскольку, если вы случайно поставите инструкцию [[BEGIN]] слишком рано или [[COMMIT]] — слишком поздно, это может сильно повлиять на то, как транзакции будут записываться в базу данных. Рекомендуется выбирать человекопонятые имена точек, по скольку это увеличит читаемость кода.
{{стиль раздела}}
Повторное использование имени точки сохранения не приведет к ошибке или выводу предупреждения, а к тому, что предыдущая точка сохранения с таким именем окажется неработоспособной.
Точки сохранения устанавливаются в пределах транзакции, в которой они определены. Имена точек сохранения должны быть уникальными в этих пределах. Используйте инструкции [[BEGIN]] и [[COMMIT]] осторожно, поскольку, если вы случайно поставите инструкцию [[BEGIN]] слишком рано или [[COMMIT]] — слишком поздно, это может сильно повлиять на то, как транзакции будут записываться в базу данных. Обязательно выбирайте для точек сохранения понятные имена, поскольку вы будете позже ссылаться на них в своих программах.
Повторное использование имени точки сохранения не приведет к ошибке или выводу предупреждения. Дублирование имени приведет к тому, что предыдущая точка сохранения с таким именем окажется неработоспособной. Будьте внимательны при выборе имен для точек сохранения!
При запуске транзакции тратятся ресурсы (а именно блокировки), обеспечивающие целостность транзакций. Ваша транзакция должна как можно быстрее завершиться, чтобы блокировки были сняты и другие пользователи могли использовать ресурсы.


== Пример ==
== Пример ==

Версия от 20:02, 12 сентября 2024

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

Указывает, что прикладная программа не может повторно использовать имя точки сохранения в блоке восстановления. Если в блоке восстановления уже существует точка сохранения с тем же именем, что и имя точки сохранения, то произойдет ошибка. Если опустить 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