Лучший способ продемонстрировать действие и последствия автономных транзакций — привести пример. Создадим простую таблицу для хранения сообщений:
ops$tkyte@ORA10G> create table t ( msg varchar2(25) );
Table created.
Таблица создана.
Далее мы создадим две процедуры, каждая из которых просто вставляет свое имя в таблицу сообщения и сразу фиксирует эту вставку. Однако одна из этих процедур будет обычной, а другая — закодированной в виде автономной транзакции. Мы используем эти объекты, чтобы показать, какая работа фиксируется в базе данных при определенных обстоятельствах.
Для начала — процедура AUTONOMOUS_INSERT:
ops$tkyte@ORA10G> create or replace procedure Autonomous_Insert
2 as
3 pragma autonomous_transaction;
4 begin
5 insert into t values ( 'Autonomous Insert' );
6 commit;
7 end;
8 /
Procedure created.
Процедура создана.
Обратите внимание на использование pragma AUTONOMOUS_TRANSACTION. Эта директива сообщает базе данных, что процедура должна выполняться как новая автономная транзакция, независимо от ее родительской транзакции.
На заметку! pragma— это просто директива компилятора, то есть метод инструктирования компилятора, чтобы он выполнил некоторую опцию компиляции. Доступны и другие pragma. Обратитесь к руководству по PL/SQL и вы увидите их полный список в указателе.
А вот — “нормальная” процедура NONAUTONOMOUS_INSERT:
ops$tkyte@ORA10G> create or replace procedure NonAutonomous_Insert
2 as
3 begin
4 insert into t values ( 'NonAutonomous Insert' );
5 commit;
6 end;
7 /
Procedure created.
Процедура создана.
Теперь давайте понаблюдаем за поведением неавтономной транзакции в анонимном блоке кода PL/SQL:
ops$tkyte@ORA10G> begin
2 insert into t values ( 'Anonymous Block' );
3 NonAutonomous_Insert;
4 rollback;
5 end;
6 /
PL/SQL procedure successfully completed.
Процедура PL/SQL успешно завершена.
ops$tkyte@ORA10G> select * from t;
MSG
Anonymous Block
NonAutonomous Insert
Как видите, работа, выполненная анонимным блоком — его оператор INSERT— была зафиксирована процедурой NONAUTONOMOUS_INSERT. Обе строки данных были зафиксированы, так что команде ROLLBACK откатывать нечего. Сравните это с поведением процедуры автономной транзакции:
ops$tkyte@ORA10G> delete from t;
2 rows deleted.
2 строки удалено.
ops$tkyte@ORA10G> commit;
Commit complete.
Фиксация завершена.
ops$tkyte@ORA10G> begin
2 insert into t values ( 'Anonymous Block' );
3 Autonomous_Insert;
4 rollback;
5 end;
6 /
PL/SQL procedure successfully completed.
Процедура PL/SQL успешно завершена.
ops$tkyte@ORA10G> select * from t;
MSG
Autonomous Insert
Здесь сохраняется только работа, выполненная и зафиксированная в автономной транзакции. Оператор INSERT, выполненный в анонимном блоке, откатывается оператором ROLLBACK в строке 4. COMMIT процедуры автономной транзакции не оказывает никакого эффекта на родительскую транзакцию, которая стартовала в анонимном блоке. По сути, здесь зафиксирована сущность автономных транзакций и то, что они делают.
Подводя итоги, можно сказать, что если вы выполняете COMMIT внутри “нормальной” процедуры, он касается не только ее собственной работы, но также всей внешней работы, выполненной в данном сеансе. Однако COMMIT, выполненный в процедуре с автономной транзакцией, распространяется только на работу этой процедуры.
< Предыдущая | Следующая > |
---|