Выбрать главу

Медленное передвижение OAT почти всегда указывает на транзакции, выполняющиеся долго. Исключение таких транзакций является одним из наилучших навыков, которые вы можете получить, обучаясь написанию клиентских приложений для Firebird.

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

* Подходят механизмы, которые завершают со временем забытые транзакции.

* Как основное правило, исключите интерфейсы просмотра данных и используйте практичные средства.

* Если использование интерфейса просмотра неизбежно, изолируйте операторы, выбирающие данные для просмотра, в транзакциях READ-ONLY READ COMMITTED.

* Убедитесь, что транзакции READ/WRITE регулярно подтверждаются - даже если пользователи используют их только для просмотра данных.

* Избегайте приложений, выполняющих произвольные запросы, включая в запросы WHERE и устанавливая ограничения по времени.

* Убедитесь, что ваши приложения имеют средства для периодического выполнения "жестких подтверждений" любых транзакций, выполняющих COMMIT RETAIN.

* Возьмите за правило использовать RollbackRetaining не более одного раза в обработчике исключений. Не помещайте RollbackRetaining внутрь циклов!

* Учитывайте, что происходит с транзакциями в сервере! Используйте gstat -h или эквивалентный инструмент для отслеживания OIT и OAT. Обращайте внимание на "зазор"[109].

* Не пренебрегайте наведением порядка в базе данных. Чистка (sweep) должна выполняться систематически. Регулярное выполнение резервного копирования, даже без восстановления базы данных, поможет поддерживать инвентарные страницы транзакций в хорошей форме[110].

Пора дальше

Теперь, когда вы освоили запутанные вопросы управления транзакциями, самое время направить ваши таланты на программирование на серверной стороне. В части VII вы начнете работать с мощными средствами, доступными в PSQL: хранимые процедуры и триггеры, обработка пользовательских исключений, механизм событий в Firebird. В главе 28 мы начнем рассматривать преимущества действий на стороне сервера для централизации бизнес-правил и сокращения сетевого трафика перед тем, как перейдем к синтаксису и техникам в следующих главах.

ЧАСТЬ VII. Программирование на сервере.

ГЛАВА 28. Введение в программирование в Firebird.

Одним из самых больших преимуществ полнокровных реализаций реляционных баз данных SQL является их способность компилировать и выполнять внутренние модули (хранимые процедуры и триггеры), представленные разработчиками в виде исходных кодов. Язык, который предоставляет такую возможность для сервера Firebird - PSQL - простой, но мощный набор расширений языка SQL, который объединяется с обычными операторами языка манипулирования данными (DML) для создания компилируемых исходных модулей.

Обзор модулей сервера

Языком высокого уровня для программирования в Firebird на стороне сервера является SQL. Исходный код предоставляется серверу в форме расширений языка программирования SQL- операторов и конструктов PSQL- и операторов DML. Сами эти операторы находятся внутри одного оператора DDL вида:

{CREATE | RECREATE | ALTER} {TRIGGER | PROCEDURE} <имя> . . .

. . .

AS

. . .

BEGIN

<один или более блоков операторов>

END

Синтаксис написания модулей PSQL подробно рассматривается в следующих главах.

Назначением каждого из этих "супероператоров DDL" является создание и сохранение одного исполняемого модуля (хранимой процедуры или триггера) или переопределение (RECREATE или ALTER) существующего объекта. Оператор DDL также используется для уничтожения (DROP) исполняемых объектов.

PSQL поддерживает три оператора манипулирования данными: INSERT, UPDATE и DELETE и возможность выборки (SELECT) одной строки или многострочных наборов элементов данных с помещением в локальные переменные. Расширения PSQL обеспечивают перечисленную далее языковую и логическую поддержку.

* Локальные переменные и операторы присваивания.

* Условные операторы управления потоком выполнения.

* Специальные контекстные переменные (только для триггеров) для доступа к старому и новому значению каждого столбца во всех входных наборах DML.

* Отправка определенных пользователем событий базы данных прослушивающим клиентам.

* Исключения, в том числе определенные пользователем, объявленные как объекты базы данных, а также (в версии 1.5) специфичные для контекста сообщения об исключениях, поддержка структуры и синтаксиса для обработки ошибок.

* Входные и выходные аргументы (только для хранимых процедур).

* Инкапсуляция поведения курсора в синтаксисе цикла FOE SELECT ... INTO ... DO.

* Оператор SUSPEND (только для хранимых процедур), предоставляющий возможность написания хранимых процедур, которые выводят виртуальную таблицу на запрос в операторе SELECT - хранимые процедуры выбора.

* Внутренние вызовы хранимых процедур в хранимых процедурах и триггерах.

* Возможность определения множества триггеров для фаз BEFORE (до) и AFTER (после) в триггерах для каждого события DML и задание их позиции в предварительно определенном порядке их исполнения. В версии 1.5 появилась возможность писать условные триггеры BEFORE и AFTER, объединяющие любые из всех возможных событий DML.

За исключением указанных специфических элементов все множество языка PSQL доступно для хранимых процедур и триггеров.

Хранимые процедуры

Хранимые процедуры могут быть использованы в приложениях различными способами.

* Процедуры выбора используются на месте таблицы или просмотра в операторе

SELECT.

* Выполняемые процедуры исполняются оператором EXECUTE PROCEDURE для выполнения одной операции или запуска множества операций на стороне сервера.

* Хранимая процедура может быть вызвана из другой хранимой процедуры или из триггера. Она может вызывать сама себя рекурсивно.

Все хранимые процедуры определяются в сложном операторе DDL CREATE PROCEDURE. Объявления выполняемых хранимых процедур и хранимых процедур выбора следуют одним и тем же синтаксическим правилам. Необязательные языковые элементы отличаются для процедур выбора и выполняемых процедур. Одна процедура может быть вложенной в другую, каждая из которых выполняет часть атомарной последовательности работы, которая будет подтверждена клиентским приложением как единое целое или отменена как целое.

Преимущества использования хранимых процедур

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

* Модульное проектирование: все приложения, имеющие доступ к одной базе данных, совместно используют хранимые процедуры, что, следовательно, централизует бизнес-правила, позволяет повторно использовать код, сокращает размер приложений.

* Хорошо налаженная поддержка: когда процедура модифицируется, изменения автоматически распространяются на все приложения без необходимости дальнейшей перекомпиляции на стороне приложения, за исключением изменений, влияющих на наборы входных или выходных аргументов.

* Улучшенное выполнение: выполнение сложной обработки делегируется серверу, сокращая сетевой трафик и нагрузки оперирования с внешними наборами.

* Экономия в архитектуре: клиентские приложения могут сфокусироваться на получении входных данных от пользователя и на управлении интерактивными задачами, в то время как серверу, который предназначен для управления данными, делегируется управление сложными данными и их зависимостями.

* Дополнительная функциональность: искусный доступ к данным, который не может быть достигнут средствами обычного SQL, может быть выполнен одной или группой хранимых процедур.

вернуться

109

Инструмент IBAnalyst (см. www.ibase.ru) выдаст все возможные предупреждения и рекомендации по поводу состояния транзакций на сервере. - Прим. науч. ред.

вернуться

110

Выполнение backup никак не влияет на Transaction Inventory Page, a sweep может продвинуть вперед OIT, но не более того. - Прим. науч. ред.