Документация Oracle на русском языке





Сайт посвящен разработке информационных систем с использованием технологий Oracle. На сайте можно найти полезную литературу и документацию на русском языке по программированию и администрированию Oracle.Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации.

Главная :: Карта


Oracle Database или Oracle RDBMS — объектно-реляционная система управления базами данных компании Oracle.



 

DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

Атомарность уровня процедуры


Интересно отметить, что Oracle также трактует анонимный блок PL/SQL как один оператор. Рассмотрим следующую хранимую процедуру: 
ops$tkyte@ORA10G> create or replace procedure p2 as 3 begin4 insert into t values ( 1 ); 
5 insert into t values (-1 );6 end;7 /
Procedure created. 
Процедура создана. 
ops$tkyte@ORA10G> select * from t;no rows selected 
нет выбранных строк 
ops$tkyte@ORA10G> select * from t2;       CNT 
Итак, у нас имеется процедура, которая, как мы знаем, завершится неудачей. Второй оператор INSERT в этом случае всегда провалится. Давайте посмотрим, что случится, если мы запустим эту хранимую процедуру: 
ops$tkyte@ORA10G> begin2 p;3 end;4 /
Я вставил и обновил 1 строк(у)Я вставил и обновил 1 строк(у)
begin* ERROR at line 1: ORA-02290: check constraint (OPS$TKYTE.SYS_C009598) violatedORA-06512: at "OPS$TKYTE.P", line 5ORA-06512: at line 2 
ОШИБКА в строке 1: ORA-02290: нарушение проверочного ограничения целостности (OPS$TKYTE.SYS_C009598) ORA-06512: в "OPS$TKYTE.P", строка 5 ORA-06512: в строке 2 
ops$tkyte@ORA10G> select * from t;no rows selected 
нет выбранных строк 
ops$tkyte@ORA10G> select * from t2;       CNT 
Как видите, СУБД Oracle трактует вызов хранимой процедуры как атомарный оператор. Клиент посылает блок кода BEGIN P; END;, а Oracle обертывает его в SAVEPOINT. Поскольку процедура P терпит неудачу, Oracle восстанавливает базу данных в состояние, которое она имела в точке, непосредственно предшествовав­шей ее вызову. Теперь, если слегка изменить блок, будет получен совершенно дру­гой результат: 
ops$tkyte@ORA10G> begin2 p; 
 3 exception4 when others then null;5 end;6 /
Я вставил и обновил 1 строк(у)Я вставил и обновил 1 строк(у)
PL/SQL procedure successfully completed.
Процедура PL/SQL успешно завершена. 
ops$tkyte@ORA10G> select * from t;X 
ops$tkyte@ORA10G> select * from t2;       CNT 
Здесь мы запускаем блок кода, игнорирующий все возможные ошибки и отли­чия в выводе. В то время как первый вызов P не проявляется ни в каких изме­нениях, этот INSERT выполняется успешно и столбец CNT в T2 соответствующим образом увеличивается. 
На заметку! Я считаю ошибочным практически любой код, который содержит обработчик исклю­чений WHEN OTHERS, но не включает вызова RAISE, чтобы передать исключение выше. Он молча игнорирует ошибку и изменяет семантику транзакций. Перехват WHEN OTHERSи транс­ляция исключения в код возврата в старом стиле изменяет способ ожидаемого поведения базы данных. 
СУБД Oracle считает “оператором” любой блок кода, присланный клиентом. Этот оператор завершается успехом за счет самостоятельного перехвата и игно­рирования ошибок, поэтому установка If error then rollback... не вступает в действие и Oracle не откатывает работу к SAVEPOINT. Поэтому частичная работа, выполненная P, сохраняется. Причина того, что эта частичная работа предохраня­ется, состоит в том, что мы имеем автономность уровня оператора внутри P: каж­дый оператор внутри P является атомарным. P становится клиентом Oracle, когда подтверждает свои два оператора INSERT. Каждый INSERT либо целиком успешен, либо нет. Это подтверждается тем фактом, что мы можем видеть, что триггер Tбыл инициирован дважды и дважды обновил T2, хотя счетчик в T2 отображает только один UPDATE. Второе выполнение INSERT внутри P снабжено неявным SAVEPOINT, обернутым вокруг него. 
Отличие между двумя блоками кода довольно-таки тонкое, и вы должны учи­тывать его в своих приложениях. Добавление обработчика исключений к блоку кода PL/SQL может радикально изменить поведение. Другой способ закодировать это — восстанавливающий атомарность уровня оператора для всего блока PL/SQL, выглядит следующим образом: 
ops$tkyte@ORA10G> begin2 savepoint sp;3 p;4 exception 
5 when others then
 6 rollback to sp;7 end;8 /
Я вставил и обновил 1 строк(у)Я вставил и обновил 1 строк(у)PL/SQL procedure successfully completed.
Процедура PL/SQL успешно завершена. 
ops$tkyte@ORA10G> select * from t;no rows selected 
нет выбранных строк 
ops$tkyte@ORA10G> select * from t2;       CNT 
Внимание! Предыдущий код представляет собой пример исключительно порочной практики. Вы никогда не должны перехватывать WHEN OTHERS, как и не должны явно кодировать то, что уже обеспечивает Oracle — до тех пор, пока речь идет о семантике транзакции. 
Здесь, имитируя то, что Oracle обычно делает для нас с помощью SAVEPOINT, мы можем восстановить оригинальное поведение, перехватывая и “игнорируя” ошибку. Я привел этот пример только для иллюстрации; вообще говоря, это ис­ключительно порочная практика. 
 


сканер hp
jAntivirus