30 дек. 2013 г.

Oracle Database 12c R1: ACCESSIBLE BY Clause in PL/SQL

Как Вы хорошо знаете, в PL/SQL нет возможности ограничить область видимости подпрограмм. Если создана PL/SQL-процедура (пакет, функция или объектный тип), то она видима в любом другом PL/SQL-объекте и в анонимном блоке, то есть может вызываться в любом месте!

До Oracle Database версии 12c R1 стандартными средствами СУБД, невозможно реализовать декларативную проверку на возможность вызова PL/SQL-процедур только в определенном месте. Например, было нельзя деклативно реализовать такую проверку: процедуры отвечающие за интерфейс пользователя, имеют право вызывать только процедуры бизнес-логики, и не могут напрямую обращаться к слою доступа к данным, иначе это может привести нарушению логической целостности данных.

В версии 12с эта проблема была устранена: при создании программной единицы PL/SQL можно указывать фразу ACCESSIBLE BY, после которой следует список PL/SQL-объектов, в которых разрешен вызов данной программной единицы.

По умолчанию, отсутствие фразы ACCESSIBLE BY подразумевает возможность вызова PL/SQL-программной единицы в произвольном месте, то есть поведение будет аналогичным как для предыдущих версий СУБД Oracle Database.

Рассмотрим уже знакомый Вам пример.
В приложении, работу с репозитарием объектов инкапсулирует объектный тип TObjectRepository. Этот объектный тип могут использовать только следующих три объектных типа:

  • TPersistent - абстрактный тип, его наследники обладают свойством сохранять и читать свое состояние из БД;
  • TDictionary - инкапсулирует работу с справочниками, в связи с особой ролью системных справочников, может напрямую обращаться к API поддержки репозитория;
  • TGroup - инкапсулирует функционал группировки объектов в группы, тоже напрямую может работать с фабрикой объектов.
В всех других программных единицах PL/SQL, обращение к типу TObjectRepository запрещено.

Итак, при создании спецификации типа TObjectRepository указываем фразу ACCESSIBLE BY

SQL> create or replace type TObjectRepository force 
  accessible by (TPersistent,TDictionary,TGroup) under TObject 
(
  static procedure registerObject(v_pObject in out nocopy TObject),

  static procedure unregisterObject(v_pObject in out nocopy TObject)

)
not final;
/

Type created.

SQL> 

Стоит отметить, что в вышеуказанном примере, типов TPersistent,TDictionary и TGroup еще не существует!

Попробуем обратится к типу TObjectRepository в неразрешенной процедуре:

SQL> create or replace procedure test_accb1 is
  v_xObject TObjectRepository;
begin
  null;
end;
/

Warning: Procedure created with compilation errors.

SQL> show errors;
Errors for PROCEDURE TEST_ACCB1:

LINE/COL ERROR
-------- -----------------------------------------------------------------
2/13  PL/SQL: Item ignored
2/13  PLS-00904: insufficient privilege to access object
  TOBJECTREPOSITORY

SQL>
Как видите, проверка производится уже на этапе компиляции. Следует отметить важное замечание: после того как для PL/SQL-программой единицы указана фраза ACCESSIBLE BY, становится невозможеным обращение к ней в анонимном блоке:

SQL> declare
  v_xObject TObjectRepository;
begin
  null;
end;
/
  v_xObject TObjectRepository;
            *
ERROR at line 2:
ORA-06550: line 2, column 13:
PLS-00904: insufficient privilege to access object TOBJECTREPOSITORY
ORA-06550: line 2, column 13:
PL/SQL: Item ignored
Поэтому, не следует применять ограничение видимости для PL/SQL-программных единиц которые применяются в вызовах верхнего уровня (top calls).

Как обстоит дело насчет проверки в runtime, то есть в время выполнения PL/SQL?
Давай-те попробуем "обмануть" компилятор и сделаем обращение к типу TObjectRepository в динамическом PL/SQL:


create or replace type body TPersistent is

  member procedure save(self in out nocopy TPersistent) is
  begin
    execute immediate 'declare v_xObject TObjectRepository; begin null; end;';
  end;

... ... ... 
При этом обращение к типу TObjectRepository происходит внутри разрешенного типа TPersistent! Однако проверка видимости все равно срабатывает:

SQL> declare
  v_xObject TPersistent;
begin
  v_xObject := new TPersistent(1);
  v_xObject.save();
end;
/
  declare
*
ERROR at line 1:
ORA-06550: line 1, column 19:
PLS-00904: insufficient privilege to access object TOBJECTREPOSITORY
ORA-06550: line 1, column 19:
PL/SQL: Item ignored
ORA-06512: at "SCOTT.TPERSISTENT", line 5
ORA-06512: at line 5
Из вышеприведенного примера следует второй важный вывод: проверка на разрешение видимости осуществляется только для текущего уровня вложенности вызов, и не учитывает более высокие уровни вызовов.
Ну и наконец, пробуем сделать обращение к типу TObjectRepository разрешенное внутри типа TPersistent:

SQL> create or replace type body TPersistent is

  member procedure save(self in out nocopy TPersistent) is
    v_xObject TObjectRepository;
  begin
    null;
  end;

... ... ... 

/

Type body created.

Появившаяся в Oracle Database 12c технология ограничения видимости программных единиц PL/SQL является полезной возможностью, которая позволяет структурировать Ваш код и защищает его от логических ошибок связанных с неверным местом вызова.

20 дек. 2013 г.

RuOUG: Oracle Database 12c High Availability New Features

19 декабря в офисе компании-дистрибьютора Марвел в рамках Российской группы пользователей Oracle (Russian Oracle User Group - RuOUG) состоялся практический семинар посвященный новым возможностям Oracle Database 12c в области обеспечения высокой доступности.
Огромная благодарность компании Марвел и лично директору направления Oracle Дмитрию Никитову за предоставленное помещение и оборудование.

На фотографии Вы видите 3-х докладчиков семинара, cлева направо: Андрей Забелин (Oracle), Андрей Басов (Марвел), Евгений Горбоконенко (Инфосистемы Джет). Ну я четвертым докладчиком был ваш покорный слуга :-)!

В лучших традициях предыдущих семинаров этот практикум был насыщен практическими занятиями: после каждой презентации проводилась лабораторная работа по соответствующей тематике.
На мой взгляд, семинары в подобном формате дают хорошую возможность углубится в новые технологии Oracle Database 12c.

Рис.1 Для проведения лаб. работ было создана 161 виртуальная машина VBox

Программа семинара выглядела следующим образом:

1 Новая архитектура Oracle RAC 12c: Flex RAC, Flex ASM
  Андрей Басов (Марвел)
2 Oracle Database 12с: Transaction Guard и Application Continuity
  Игорь Мельников (Oracle)
3 Oracle Database 12с Global Data Services
  Андрей Забелин (Oracle)
4 Oracle Active Dataguard 12с – новые возможности
  Евгений Горбоконенко (Инфосистемы Джет)

Немного фактов:

  • все практические занятия проводились в среде Oracle Database 12.1.0.1 работающей под управлением Oracle Linux 6 Update 5 for x86-64;
  • всего было создано 161 (!!!) виртуальная машина VirtualBox для проведения занятий;
  • суммарно образы ВМ заняли 2,5 Тб дискового пространства;
  • для запуска виртуальных машин был использован 4-х процессорный сервер Sun X2-4 с 128Гб оперативной памяти на борту;
  • пиковая загрузка хост-сервера была зафиксирована в момент проведения лабораторной работы по Active DataGuard FarSync

Фото 1. На презентации Евгения Горбоконенко про Active Dataguard Far Sync 12c

Также хотелось бы поблагодарить всех участников RuOUG, кто пришел на этот семинар. Этот семинар проводился впервые и возникли неизбежные технические проблемы и мелкие недочеты в лабораторных работах. Но опытных профессионалов это не испугало! :-)
Конечно, в будущем, мы учтем все замечания и пожелания.

Фото 2. Хост-сервер для виртуальных машин

Вы здесь вы можете скачать и посмотреть мою лабораторную работу по использованию технологии Transaction Guard и Application Continuity. Вот собственно сама презентация по этой теме.

Рис 2. Хост-сервер: идут лабораторные работы по Active Dataguard Far Sync

В будущем планируется повторение этого семинара на площадке представительства Oracle в СНГ. Также мы планируем проведение семинаров в подобном формате и по другим интересным технологиям Oracle 12c, прежде всего по Pluggable Database.


Следите за объявлениями!
Увидимся в Oracle Database 12c! :-)