|
Программирование >> Oracle
1182 Глава 15 Именно этого мы и ожидали. Функция F б]ла вызвана 28 раз (14 из них - для запросов в операторе UNION). Поскольку при выполнении оператора UNION в качестве побочного эффекта происходит сортировка для поиска неповторяющихся значений (SORT DISTINCT), функция COUNT(*) по объединению дает 1 (и это правильно), а функция, как и ожидалось, вызывалась 28 раз. Слегка изменим запрос: tkyte@TKYTE816>update counter set x = 0; 1 row updated. tkyte@TKYTE816> commit; Coit complete. tkyte@TKYTE816> select f from emp union ALL select f from emp 2 / 28 rows selected. tkyte@TKYTE816> select * from counter; X Запрос вернул 28 строк, но наша функция б]ла вызвана 32 раза! Помните о побоч-н1х эффектах. Сервер Oracle не гарантирует, что функция вообще будет вызвана (вспомните первый пример) или будет вызвана определенное количество раз (последний пример). Будьте особенно осторожны при использовании таких изменяющих базу даннтх функций в SQL-операторах, если используется другая таблица, кроме DUAL, выполняются соединения, сортировки и т.п. Результаты могут оказаться неожиданными. Разработка модульного кода Автономные транзакции также позволяют повысить модульность кода. Традиционно создается набор пакетов, выполняющих некоторые действия. Эти действия представляют собой ряд изменений в базе данных, которые, в зависимости от результатов, фиксируются или откатываются. Все это замечательно, если надо заботиться только о своих процедурах. В крупномасштабном приложении, однако, ваш простой пакет будет далеко не единственным компонентом. Скорее всего, он будет лишь небольшой частью общей картины. В типичной процедуре фиксируются не только выполненные в ней изменения, но и все не зафиксированные изменения, выполненные в сеансе до вызова этой процедуры. При фиксации постоянными делаются все эти изменения. Проблема в том, что выполнявшиеся до вызова процедуры изменения могут быть не завершены. Поэтому выполнение оператора COMMIT может привести к ошибке в вызывающей процедуре. Она Автономные транзакции 1183 уже не сможет откатить выполненные изменения в случае сбоя, даже не подозревая об этом. С помощью автономных транзакций теперь можно создавать самодостаточные подпрограммы, выполняющие транзакции, которые не влияют на состояние вызывающих транзакций. Это может быть весьма полезно для многих типов подпрограмм, в частности, реализующих проверку, журнализацию и другие служебные функции. Так можно создавать код, который безопасно вызывать из различных сред, не влияя деструктивно на функционирование этих сред. Использование автономных транзакций для проверки, журнализации и других служебнтх функций - вполне оправдано. Лично я считаю фиксацию транзакций в хранимых процедурах обоснованной только в перечисленных случаях. Я считаю, что фиксировать транзакции должно только клиентское приложение. Необходимо быть осторожным и использовать автономные транзакции правильно. Если код должен вызываться как логическая часть более масштабной транзакции (например, если создан пакет ADDRESS UPDATE для системы учета кадров), то оформлять его в виде автономной транзакции нельзя. Во внешней среде необходимо обеспечить возможность вызова этого пакета и других соответствующих пакетов, а затем зафиксировать (или отменить) все изменения в целом. Поэтому при использовании автономной транзакции контроль из вызывающей среды невозможен, как и построение больших транзакций из меньших составнтх частей. Кроме того, автономная транзакция не видит незафиксированных изменений, выполненных в вызывающей транзакции. Подробнее это описано в разделе Какработают автономные транзакции . Это означает, что для автономной транзакции незафиксированные изменения остальной кадровой информации будут невидимы. Для корректного использования автономных транзакций необходимо четко представлять все возможные варианты использования создаваемого кода. Как работают автономные транзакции В этом разделе я опишу, как работают автономные транзакции и чего от них можно ожидать. Мы изучим последовательность действий при выполнении автономных транзакций. Мы также рассмотрим, как автономные транзакции влияют на область действия различных элементов - переменных пакетов, параметров сеансов, параметров базы данных и блокировок. Мы поговорим о том, как правильно завершать автономную транзакцию, и о точках сохранения. Выполнение транзакции Выполнение автономной транзакции начинается с ключевого слова BEGIN и завершается ключевым словом END. To есть, при наличии следующего блока кода: declare pragma autonomous transaction; X number default func; (1) begin (2) end; (3) 1184 Глава 15 автономная транзакция начинается со строки (2), а не (1). Она начинается с первого выполняемого оператора. Если FUNC - функция, выполняющая изменения в базе данных, - эти изменения не являются частью автономной транзакции. Они - часть родительской транзакции. Кроме того, порядок следования элементов в разделе DECLARE блока не имеет значения: конструкция PRAGMA может быть как первой, так и последней. Весь раздел DECLARE блока является частью родительской транзакции, а не автономной. Следующий пример поможет это прояснить: tkyte@TKYTE816> create table t (msg varchar2(50)); Table created. tkyte@TKYTE816> create or replace function func return number 2 as 3 begin 4 insert into t values 5 (Строка вставлена функцией FUNC) ; 6 return 0; 7 end ; Function created. Итак, имеется функция, изменяющая базу данных. Давайте теперь вызовем эту функцию в разделе DECLARE блока, оформленного как автономная транзакция: tkyte@TKYTE816> declare 2 x number default func; 3 pragma autonomous transaction; 4 begin 5 insert into t values 6 (Строка вставлена анонный блоком); 7 commit; 8 end; PL/SQL procedure successfully completed. tkyte@TKYTE816> select * from t; Строка вставлена функцией FUNC Строка вставлена анонимным блоком Пока что обе строки есть. Однако одна из строк еще не зафиксирована. В этом можно убедиться, выполнив откат: tkyte@TKYTE816> rollback; Rollback complete. tkyte@TKYTE816> select * from t; Строка вставлена анонимным блоком
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |