|
Программирование >> Oracle
1200 Глава 15 ной транзакции невидимы выполняемые нами изменения. Поэтому такое увеличение зарплаты и проходит: процедура проверяет таблицу по состоянию до начала этого изменения! С нарушением столкнется следующий невезучий пользователь (как мы продемонстрировали, искусственно вызвав процедуру SALCHECK). При любом использовании автономной транзакции во избежание проблемы изменяющейся таблицы убедитесь, что вы поступаете правильно. В разделе Проверка, записи которой не могут быть отменены я использовал автономную транзакцию безопасным способом. Логика работы триггера не нарушается из-за того, что таблица в нем видна в состоянии до начала транзакции. В представленном выше примере триггер от этого существенно пострадал. Необходимо быть особенно внимательным и проверять корректность каждого триггера, оформленного как автономная транзакция. Ошибки, которые могут произойти При работе с автономными транзакциями может произойти несколько ошибок. Для полноты изложения соответствующие сообщения представлены и прокомментированы ниже, но большинство них мы уже встречали в примерах. В этом разделе текст сообщения об ошибке приведен так, как он в]дается СУБД Oracle версии 8.1.6.0.0 при установке русского языка для сообщений. Обратите внимание на несоответствие терминологии, предлагаемой компанией Oracle. В примерах оставлены сообщения на английском языке. - Прим. научн. ред. ORA-06519: выполнен откат назад для незавершенной автономной транзакции * Причина: Перед выходом из автономного PL/SQL-блока все начатые в нем автономные транзакции должны быть завершены (зафиксованы или отменены) . В противном случае активная автономная транзакция неявно откатывается и выдается это сообщение об ошибке. * Действие: Убедитесь, что перед в1ходом из автономного PL/SQL-блока все активные автономные транзакции явно зафиксированы или отменены. Это сообщение об ошибке выдается каждый раз при выходе из автономной транзакции, если перед этим не позаботились о ее явной фиксации или откате. При этом автономная транзакция откатывается, а исключительная ситуация распространяется в среду, откуда автономная транзакция бтла вызвана. Чтобы избавиться от этой проблемы, следует всегда обеспечивать фиксацию или откат транзакции для всех вариантов завершения PL/SQL-блока, оформленного как автономная транзакция. Эта ошибка всегда связана с логической ошибкой в коде. ORA-14450: попытка доступа к уже используемой временной таблице транзакций * Причина: Выполнена попытка доступа к временной таблице уровня транзакции, данные в которую поместила другая транзакция, одновременно выполняющаяся в том же сеансе. Автономные транзакции 1201 * Действие: Не пытайтесь обращаться к временной таблице, пока одновременно выполняющаяся транзакция не будет зафиксована или отменена. Как было продемонстрировано ранее, глобальная временная таблица, созданная с опцией ON COMMIT DELETE ROWS, может использоваться только одной транзакцией в сеансе. Необходимо не допускать использования одной временной таблицы в родительской и порожденной транзакции. ORA-00060: взаимная блокировка при ожидании ресурса * Причина: Произошла взаная блокировка транзакций при ожидании ресурса. * Действие: Определите по трассировочному файлу, какие транзакции и ресурсы стали причиной взаимной блокировки. При необходости повторите транзакцию. Эта ошибка не связана непосредственно с использованием автономных транзакций, но я представил ее здесь потому, что при использовании автономных транзакций повышается вероятность ее возникновения. Поскольку родительская транзакция приостанавливается на время выполнения порожденной транзакции, и не может продолжить работу до ее завершения, взаимная блокировка, не возникающая при одновременной работе двух сеансов, возникает при использовании автономной транзакции. Она произойдет при попытке изменить одни и те же данные в двух отдельных транзакциях одного сеанса. Необходимо проверять, не пытается ли порожденная транзакция заблокировать ресурсы, уже заблокированные родительской транзакцией. Резюме В этой главе мы детально изучили возможности автономных транзакций. Вы увидели, как их можно использовать для создания более модульного и безопасного кода. Вы научились выполнять с их помощью невозможные до этого действия (например, выполнять операторы ЯОД в триггере или вызывать в операторе SELECT хранимую функцию независимо от того, изменяет ли она базу данных). Я объяснил, почему неразумно предполагать, что функция, вызываемая в SQL-операторе, будет выполнена определенное количество раз, и поэтому надо быть особенно осторожным при изменении базы данных в таких функциях. Вы узнали, как с помощью автономных транзакций избежать проблемы изменяющейся таблицы, и что они могут привести к ошибочному результату при некорректном использовании для решения этой проблемы. Автономные транзакции - мощное средство, которое сервер Oracle использует уже многие годы для выполнения рекурсивных SQL-операторов. Теперь их можно использовать и в приложениях. Прежде чем использовать это средство, надо хорошо понимать, как выполняются транзакции, когда они начинаются и когда заканчиваются, поскольку могут возникать различные побочные эффекты. Например, сеанс может заблокировать сам себя, родительская транзакция может видеть или не видеть результаты порожденной автономной, порожденная автономная транзакция не видит незафиксированные результаты родительской и т.д. Динамический SQL Обычно при разработке программ все используемые в них SQL-операторы явно записываются в исходном коде. Такой вариант использования SQL-операторов обычно называют статический SQL. Многие полезные программы, однако, до момента запуска не знают , какие именно SQL-операторы будут выполняться. Именно так и появляется динамический SQL - программа при запуске выполняет SQL-операторы, неизвестные во время компиляции. Возможно, программа генерирует запросы по ходу работы на основе введеннтх пользователем условий; возможно, это специализированная программа загрузки данных. Утилита SQL*Plus - прекрасный пример такого рода программы, как и любое другое средство выполнения произвольных запросов или генерации отчетов. Утилита SQL*Plus позволяет выполнить любой SQL-оператор и показать результаты его выполнения* хотя при ее компиляции операторы, которые выполняет пользователь, определенно не были известны. В этой главе мы обсудим, когда возникает необходимость использовать динамический SQL в программах и когда его имеет смысл применять. Мы сосредоточимся на использовании динамического SQL в программах на языке PL/SQL, поскольку именно в этой среде большинство разработчиков и используют динамический SQL в предварительно компилируемом формате. Поскольку использование динамического SQL - единственный способ выполнить SQL-операторы в программах на языке Java через интерфейс JDBC (выполнить динамический SQL в среде прекомпилятора SQLJ можно только через интерфейс JDBC) и на языке С при использовании библиотеки OCI, не имеет смысла обсуждать эти среды в данном контексте. В этих средах есть только динамический SQL; статический SQL вообще не поддерживается, так что там просто нет выбора. Мы же в данной главе:
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |