Oracle поддерживает очень мощную и надежную модель транзакций. Код приложения определяет логическую последовательность выполняемых операций, результаты которой должны быть либо сохранены командой COMMIT
, либо отменены командой ROLLBACK.
Транзакция начинается неявно с первой команды SQL
, выполняемой после команды COMMIT
или ROLLBACK
(или с начала сеанса) или же после команды ROLLBACK TO SAVEPOINT
. Для управления транзакциями PL/SQL
предоставляет набор команд:
COMMIT
— сохраняет (фиксирует) все изменения, внесенные со времени выполнения последней командыCOMMIT
илиROLLBACK
, и снимает все блокировки.ROLLBACK
— отменяет (откатывает) все изменения, внесенные со времени выполнения последней командыCOMMIT
илиROLLBACK
, и снимает все блокировки.ROLLBACK TO SAVEPOINT
— отменяет все изменения со времени установки последней точки сохранения и снимает все блокировки, установленные в этой части кода.- SAVEPOINT — устанавливает точку сохранения, после чего становится возможным частичный откат транзакции.
SET TRANSACTION
— позволяет начать сеанс чтения или чтения-записи, установить уровень изоляции или связать текущую транзакцию с заданным сегментом отката.LOCK TABLE
— позволяет заблокировать всю таблицу в указанном режиме. (По умолчанию к таблице обычно применяется блокировка на уровне строк.)
Эти команды более подробно рассматриваются в следующих разделах блога.
Команда COMMIT
Фиксирует все изменения, внесенные в базу данных в ходе сеанса текущей транзакцией. После выполнения этой команды изменения становятся видимыми для других сеансов или пользователей. Синтаксис этой команды:
COMMIT [WORK] [COMMENT текст];
Ключевое слово WORK
не обязательно — оно только упрощает чтение кода.
Ключевое слово COMMENT
также не является обязательным; оно используется для задания комментария, который будет связан с текущей транзакцией. Текстом комментария должен быть заключенный в одинарные кавычки литерал длиной до 50 символов. Обычно комментарии задаются для распределенных транзакций с целью облегчения их анализа и разрешения сомнительных транзакций в среде с двухфазовой фиксацией. Они хранятся в словаре данных вместе с идентификаторами транзакций.
Обратите внимание: команда COMMIT
снимает все блокировки таблиц, установленные во время текущего сеанса (например, для команды SELECT FOR UPDATE
). Кроме того, она удаляет все точки сохранения, установленные после выполнения последней команды COMMIT
или ROLLBACK
.
После того как изменения будут закреплены, их откат становится невозможным.
Все команды в следующем фрагменте являются допустимыми применениями COMMIT
:
COMMIT;
COMMIT WORK;
COMMIT COMMENT 'maintaining account balance'.
Команда ROLLBACK
Команда ROLLBACK
отменяет (полностью или частично) изменения, внесенные в базу данных в текущей транзакции. Для чего это может потребоваться? Например, для исправления ошибок:
DELETE FROM orders;
«Нет, Нет! Я хотел удалить только те заказы, которые были сделаны до мая 2005 года!» Нет проблем — достаточно выполнить команду ROLLBACK. Что касается программирования приложений, в случае возникновения проблем откат позволяет вернуться к исходному состоянию.
Синтаксис команды ROLLBACK
:
ROLLBACK [WORK] [TO [SAVEPOINT] имя_точки_сохранения];
Существует две основные разновидности ROLLBACK
: без параметров и с секцией TO, указывающей, до какой точки сохранения следует произвести откат. Первая отменяет все изменения, выполненные в ходе текущей транзакции, а вторая отменяет все изменения и снимает все блокировки, установленные после заданной точки сохранения. (О том, как установить в приложении точку сохранения, рассказано в следующем разделе.) Имя точки сохранения представляет собой необъявленный идентификатор Oracle
. Это не может быть литерал (заключенный в кавычки) или имя переменной.
Все команды ROLLBACK
в следующем фрагменте действительны :
ROLLBACK;
ROLLBACK WORK;
ROLLBACK TO begin_cleanup;
При откате до заданной точки сохранения все установленные после нее точки стираются, но данная точка остается. Это означает, что можно возобновить с нее транзакцию и при необходимости снова вернуться к этой же точке сохранения.
Непосредственно перед выполнением команды INSERT
, UPDATE
, MERGE
или DELETE PL/SQL
автоматически устанавливает неявную точку сохранения, и если команда завершается ошибкой, выполняется автоматический откат до этой точки. Если в дальнейшем в ходе выполнения команды DML происходит сбой, выполняется автоматический откат до этой точки. Подобным образом отменяется только последняя команда DML
.
Команда SAVEPOINT
Устанавливает в транзакции именованный маркер, позволяющий в случае необходимости выполнить откат до отмеченной точки сохранения. При таком откате отменяются все изменения и удаляются все блокировки после этой точки, но сохраняются изменения и блокировки, предшествовавшие ей. Синтаксис команды SAVEPOINT
:
SAVEPOINT имя_точки_сохранения;
Здесь имя точки сохранения — необъявленный идентификатор. Он должен соответствовать общим правилам формирования идентификаторов Oracle (до 30 символов, начинается с буквы, состоит из букв, цифр и символов #, $ и _), но объявлять его не нужно (да и невозможно).
Область действия точки сохранения не ограничивается блоком PL/SQL, в котором она установлена. Если в ходе транзакции имя точки сохранения используется повторно, эта точка просто «перемещается» в новую позицию, причем независимо от процедуры, функции или анонимного блока, в котором выполняется команда SAVEPOINT
. Если точка сохранения устанавливается в рекурсивной программе, на самом деле на каждом уровне рекурсии она задается заново, но откат может быть возможен только к одной точке — той, что установлена последней.
Команда SET TRANSACTION
Команда SET TRANSACTION
позволяет начать сеанс чтения или чтения-записи, установить уровень изоляции или связать текущую транзакцию с заданным сегментом отката. Эта команда должна быть первой командой SQL
транзакции и дважды использоваться в ходе одной транзакции не может. У нее имеются четыре разновидности.
-
SET TRANSACTION READ ONLY
— определяет текущую транзакцию доступной «только для чтения». В транзакциях этого типа всем запросам доступны лишь те изменения, которые были зафиксированы до начала транзакции. Они применяются, в частности, в медленно формируемых отчетах со множеством запросов, благодаря чему в них часто используются строго согласованные данные. -
SET TRANSACTION READ WRITE
— определяет текущую транзакцию как операцию чтения и записи данных в таблицу. SET TRANSACTION ISOLATION LEVEL SERIALIZABLE | READ COMMITTED
— определяет способ выполнения транзакции, модифицирующей базу данных. С ее помощью можно задать один из двух уровней изоляции транзакции:SERIALIZABLE
илиREAD COMMITTED
. В первом случае командеDML
, пытающейся модифицировать таблицу, которая уже изменена незафиксированной транзакцией, будет отказано в этой операции. Для выполнения этой команды в инициализационном параметре COMPATIBLE базы данных должна быть задана версия 7.3.0 и выше.При установке уровняREAD COMMITED
командаDML
, которой требуется доступ к строке, заблокированной другой транзакцией, будет ждать снятия этой блокировки.SET TRANSACTION USE ROLLBACK SEGMENT
имя сегмента — назначает текущей транзакции заданный сегмент отката и определяет ей доступ «только для чтения». Не может использоваться совместно с командойSET TRANSACTION READ ONLY
.
Механизм сегментов отката считается устаревшим; вместо него следует использовать средства автоматического управления отменой, введенные в Oracle9i.
Команда LOCK TABLE
Команда блокирует всю таблицу базы данных в указанном режиме. Блокировка запрещает или разрешает модификацию данных таблицы со стороны других транзакций на то время, пока вы с ней работаете. Синтаксис команды LOCK TABLE
:
LOCK TABLE
список_таблиц IN режим_блокировки MODE [NOWAIT];
Здесь список таблиц — список из одной или нескольких таблиц (локальных таблиц/пред- ставлений или доступных через удаленное подключение), а режим блокировки — один из шести режимов: ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE.
Если команда содержит ключевое слово NOWAIT
, база данных не ждет снятия блокировки в том случае, если нужная таблица заблокирована другим пользователем, и выдает сообщение об ошибке. Если ключевое слово NOWAIT
не указано, Oracle ждет освобождения таблицы в течение неограниченно долгого времени. Блокировка таблицы не мешает другим пользователям считывать из нее данные.
Примеры допустимых команд LOCK TABLE
:
LOCK TABLE emp IN ROW EXCLUSIVE MODE;
LOCK TABLE emp, dept IN SHARE MODE NOWAIT;
LOCK TABLE scott.emp@new_york IN SHARE UPDATE MODE;
Там, где это возможно, используйте стандартные средства блокировки Oracle
. Команду LOCK TABLE
в приложениях следует использовать только в крайних случаях и с величайшей осторожностью.