Атомарные транзакции начального блока в PL / SQL
эту информацию должно быть легко найти, но мне не повезло.
когда у меня есть BEGIN - END
блок в PL / SQL, он ведет себя как атомарная транзакция, которая попытается совершить удар по END
блок и если что-то пойдет не так, откат изменений?
Если нет, как я могу убедиться, что код внутри блока BEGIN - END ведет себя как атомарная транзакция и как блок ведет себя "по умолчанию"?
EDIT: я бегу от хранимая процедура, и я использую неявный блок, я думаю.
3 ответов
во-первых, BEGIN..END
просто синтаксические элементы, и не имеют ничего общего с транзакциями.
во-вторых, в Oracle все отдельные операторы DML являются атомарными (т. е. они либо полностью преуспевают, либо откатывают любые промежуточные изменения при первом сбое) (если вы не используете исключения в опцию, в которую я не буду входить здесь).
Если вы хотите, чтобы группа операторов рассматривалась как одна атомарная транзакция, вы бы сделали что-то вроде это:
BEGIN
SAVEPOINT start_tran;
INSERT INTO .... ; -- first DML
UPDATE .... ; -- second DML
BEGIN ... END; -- some other work
UPDATE .... ; -- final DML
EXCEPTION
WHEN OTHERS THEN
ROLLBACK TO start_tran;
RAISE;
END;
таким образом, любое исключение приведет к откату операторов в этом блоке, но любые операторы, которые были запущены до этого блока не будет откатываться.
обратите внимание, что я не включаю фиксацию-обычно я предпочитаю, чтобы вызывающий процесс выдавал фиксацию.
Это правда, что начало..END block без исключения обработчик автоматически обработает это для вас:
BEGIN
INSERT INTO .... ; -- first DML
UPDATE .... ; -- second DML
BEGIN ... END; -- some other work
UPDATE .... ; -- final DML
END;
Если исключение поднятые, все вставки и обновления будут откатываться; но как только вы захотите добавить обработчик исключений, он не будет откатываться. Поэтому я предпочитаю явный метод, используя savepoints.
BEGIN
-END
блоки являются строительными блоками PL/SQL, и каждый блок PL / SQL содержится по крайней мере в одном таком блоке. Гнездование BEGIN
-END
блоки в блоках PL/SQL обычно выполняются для ловушки определенных исключений и обработки этого специального исключения, а затем вызывают несвязанные исключения. Тем не менее, в PL/SQL, вы (клиент) должны всегда выдает commit или rollback для транзакций.
если вы хотите иметь атомарные транзакции в PL / SQL, содержащие транзакция, вам нужно объявить PRAGMA AUTONOMOUS_TRANSACTION
в блоке объявления. Это гарантирует, что любой DML в этом блоке может быть зафиксирован или откат независимо от содержащей транзакции.
однако вы не можете объявить эту прагму для вложенных блоков. Вы можете объявить это только для:
- блоки верхнего уровня (не вложенные) анонимные PL/SQL
- элемент списка
- локальные, автономные и упакованные функции и процедуры
- методы типа объекта SQL
- триггеры базы данных
ссылки: Oracle
вы не упоминаете, является ли это анонимный блок PL / SQL или декларативный ie. Пакет, процедура или функция. Однако в PL/SQL фиксация должна быть явно сделана, чтобы сохранить транзакции в базе данных. Фиксация фактически сохраняет все несохраненные транзакции в базе данных изсессии.
Если возникает ошибка, транзакция неявно выполняет откат.
Это поведение по умолчанию для PL / SQL.