Откат в PLSQL Exception - PullRequest
       12

Откат в PLSQL Exception

4 голосов
/ 23 ноября 2011

Хотелось бы знать, требуется ли откат при обнаружении исключения SQL (исключение при других):

declare
 cursor c_test is
    select    *
    from  tesing;
    begin
       for rec in c_test loop
       begin
           update test1 set test1.name=rec.name where test1.id=rec.id;
           IF sql%rowcount = 1 THEN
                            commit;
           ELSIF   sql%rowcount =0 THEN
                   dbms_output.put_line('No Rows Updated');
           else
                  dbms_output.put_line('More than 1 row exists');
                  rollback;
           END IF;
       exception when others then
                  dbms_output.put_line(Exception');
                  rollback;
      end;      

end;

1 Ответ

17 голосов
/ 23 ноября 2011

Во-первых, я предполагаю, что мы можем игнорировать синтаксические ошибки (например, нет END LOOP, в вызове dbms_output.put_line отсутствует первая одинарная кавычка и т. Д.)

От того, нужно ли откатывать изменения, зависит.

В общем, у вас не было бы временных коммитов в цикле. Как правило, это плохая архитектура, поскольку она намного дороже с точки зрения ввода-вывода и затраченного времени. Это также усложняет написание перезапускаемого кода. Что происходит, например, если ваш оператор SELECT выбирает 10 строк, вы выпускаете (и фиксируете) 5 обновлений, а затем 6-е обновление завершается неудачно? Единственный способ перезапустить 6-ю строку после исправления исключения - это иметь отдельную таблицу, в которой вы сохраняли (и обновляли) ход выполнения вашего кода. Это также создает проблемы для любого кода, который вызывает этот блок, который должен обрабатывать случай, когда половина работы была выполнена (и зафиксирована), а другая половина - нет.

В общем случае вы должны размещать операторы управления транзакциями только в самых внешних блоках вашего кода. Поскольку COMMIT или ROLLBACK в процедуре фиксирует или откатывает любую работу, выполненную в сеансе, независимо от того, была ли она выполнена процедурой, вы должны быть очень осторожны при добавлении операторов управления транзакциями. Как правило, вы хотите, чтобы вызывающий абонент решал, фиксировать или откатывать. Конечно, это заходит так далеко - в конце концов, вы окажетесь в самом внешнем блоке, который никогда не будет вызываться из какой-либо другой подпрограммы, и вам необходимо иметь соответствующий контроль транзакций - но это что-то очень осторожное о том, если вы пишете код, который может быть использован повторно.

В этом случае, поскольку у вас есть временные коммиты, единственный эффект вашего ROLLBACK будет состоять в том, что если первый оператор обновления потерпит неудачу, работа, которая была выполнена в вашем сеансе до вызова этого блока, будет откатываться. Временная фиксация передаст эти предыдущие изменения, если первый оператор обновления был успешным. Это тот побочный эффект, о котором беспокоятся люди, когда говорят о том, почему временные коммиты и управление транзакциями в повторно используемых блоках проблематичны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...