Вопрос по plsql, oracle – BEGIN - END блок атомарных транзакций в PL / SQL

47

Эту информацию легко найти, но мне не повезло.

Когда у меняBEGIN - END блок в PL / SQL, он ведет себя как атомарная транзакция, которая попытается зафиксировать при нажатииEND заблокировать и если что пойдет не так откатит изменения?

Если нет, то как мне убедиться, что код внутри блока BEGIN - END ведет себя как атомарная транзакция, и как блок ведет себя по умолчанию?

РЕДАКТИРОВАТЬ: я запускаю из хранимой процедуры и я использую неявный блок, я думаю.

Вы должны выдать явныйCOMMIT а такжеROLLBACK заявления (возможно, вEXCEPTION раздел), если это поведение, которое вы ищете. Если вы действительно хотите атомарную транзакцию, загляните в AUTONOMOUS_TRANSACTIONS в Oracle. Ollie

Ваш Ответ

3   ответа
63

Во-первых,BEGIN..END являются просто синтаксическими элементами и не имеют ничего общего с транзакциями.

Во-вторых, в Oracle все отдельные операторы DML являются атомарными (то есть они либо полностью завершаются успешно, либо откатывают любые промежуточные изменения при первом сбое) (если вы не используете опцию EXCEPTIONS INTO, в которую я не буду здесь переходить).

Если вы хотите, чтобы группа операторов рассматривалась как одна атомарная транзакция, вы должны сделать что-то вроде этого:

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;

Таким образом, любое исключение вызовет откат операторов в этом блоке, но все операторы, которые были выполненыprior to this block откат не будет.

Обратите внимание, что я не включаю COMMIT - обычно я предпочитаю, чтобы вызывающий процесс выдал коммит.

Это правда, что блок BEGIN..END без обработчика исключений автоматически обработает это для вас:

BEGIN
  INSERT INTO .... ; -- first DML
  UPDATE .... ; -- second DML
  BEGIN ... END; -- some other work
  UPDATE .... ; -- final DML
END;

Если возникает исключение, все вставки и обновления будут откатываться; но как только вы захотите добавить обработчик исключений, он не будет отменен. Поэтому я предпочитаю явный метод с использованием точек сохранения.

это транзакция, если используются вложенные блоки с обработкой исключений, но без обработки исключений в основном / внешнем блоке?
@JonnyLeeds, нет, это транзакция, когда вы запускаете операторы DML.
5

BEGIN-END блоки являются строительными блоками PL / SQL, и каждый модуль PL / SQL содержится как минимум в одном таком блоке. гнездованиеBEGIN-END блоки внутри блоков PL / SQL обычно выполняются для перехвата определенных исключений и обработки этого специального исключения, а затем для вызова несвязанных исключений. Тем не менее, в PL / SQL вы (клиент) должны всегда выполнять фиксацию или откат транзакции.

Если вы хотите иметь атомарные транзакции в транзакции, содержащей PL / SQL, вам нужно объявитьPRAGMA AUTONOMOUS_TRANSACTION в блоке декларации. Это обеспечит возможность фиксации или отката любого DML в этом блоке независимо от содержащейся транзакции.

Однако вы не можете объявить эту прагму для вложенных блоков. Вы можете объявить это только для:

Top-level (not nested) anonymous PL/SQL blocks List item Local, standalone, and packaged functions and procedures Methods of a SQL object type Database triggers

Ссылка:оракул

0

Вы не упоминаете, является ли это анонимным блоком PL / SQL или декларативным, т.е. Пакет, Процедура или Функция. Однако в PL / SQL необходимо явно указать COMMIT для сохранения ваших транзакций в базе данных. COMMIT фактически сохраняет все несохраненные транзакции в базе данных от ваших текущих пользователей.session.

Если происходит ошибка, транзакция неявно выполняет ROLLBACK.

Это поведение по умолчанию для PL / SQL.

Я не уверен, что правильно сказать, чтоtransaction делает откат; все незавершенные изменения, сделанные до того, как PL / SQL-блок все еще находится на рассмотрении, и клиент должен подтвердить или отменить их. Любые действия, предпринятые в блоке, будут откатываться, как если бы это была точка сохранения, что, я думаю, и имеет в виду. (По-прежнему,Tom explains better than I can). Я также не уверен, запрашивает ли OP запрос о вложенном блоке в блоке и будут ли изменения во внутреннем блоке фиксироваться / откатываться независимо.

Похожие вопросы