Атомарные транзакции начального блока в 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.