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

GRADE SMALLINT)

AS

BEGIN

FOR SELECT job_code, job_title, job_grade FROM job

WHERE JOB_CODNTRY = :COUNTRY

INTO :CODE, :TITLE, :GRADE

DO

BEGIN /* начало цикла */

CODE = 'CODE: ' || CODE; /* немного похулиганить с этим значением */

SUSPEND; /* выводит одну строку цикла */

END

END

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

SELECT * FROM SHOW_JOBS_FOR_COUNTRY ('England');

CODE TITLE GRADE

CODE: Admin Administrative Assistant 5

CODE: Eng Engineer 4

CODE: Sales Sales Co-ordinator 3

CODE: SRep Sales Representative 4

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

Внешние виртуальные таблицы

Внешняя виртуальная таблица (EVT) является таблицей, которая получает данные от некоторого внешнего источника данных, а не из базы данных. Результаты запроса к EVT трактуются точно тем же образом, что и результаты любого другого запроса, они выглядят точно так же, как если бы они были получены из таблицы базы данных. Это позволяет интегрировать такие внешние данные, как источники данных реального времени, форматированные данные файлов операционной системы, другие базы данных (включая даже не реляционные базы данных), а также любые другие источники табулированных данных.

Firebird реализует внешние виртуальные таблицы с помощью предложения EXTERNAL FILE оператора CREATE TABLE. Внешние данные читаются из текстовых записей фиксированного формата в обычные столбцы данных Firebird.

Внешние таблицы Firebird могут также добавлять записи во внешние виртуальные таблицы.

См. разд. "Использование внешних файлов в качестве таблиц" главы 16.

Пора дальше

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

ЧАСТЬ VI. Транзакции.

ГЛАВА 25. Обзор транзакций Firebird.

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

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

* Потеря изменений (lost updates) появляется, когда два пользователя просматривают один и тот же набор, и один пользователь выполняет изменения, за которыми сразу же следуют изменения другого пользователя, перекрывающие работу первого пользователя.

* "Грязное" чтение (dirty read) позволяет одному пользователю видеть изменения, которые у другого пользователя находятся в процессе выполнения, без гарантии того, что изменения другого пользователя являются окончательными.

* Невоспроизводимое чтение (non-reproducible-reads) позволяет одному пользователю непрерывно выбирать строки, которые другие пользователи изменяют или удаляют. Эта проблема зависит от среды. Например, финансовые процессы по концу месяца или инвентаризация будут ошибочными в этих условиях, поскольку приложению продажи билетов нужно содержать все пользовательские представления синхронизированными, чтобы исключить двойные заказы.

* Фантомные строки (phanthom rows) появляются, когда один пользователь может выбирать некоторые, но не все новые строки, введенные другими пользователями. Опять же, это может быть применимо в одних ситуациях, однако это будет искажать результаты некоторых процессов.

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

Для решения таких проблем Firebird использует модель управления, которая изолирует каждую задачу внутри уникального контекста, ограничивающего последствия, если работа такой задачи может вызвать перекрытие работы, выполненной другими задачами. Состояние базы данных не может изменяться, если существуют какие-либо конфликты.

! ! !

ПРИМЕЧАНИЕ. Firebird не допускает "грязное" чтение. При некоторых условиях он специально позволяет невоспроизводимое чтение.

. ! .

Свойства ACID

Сейчас прошло уже более 20 лет с того времени, как два исследователя, Тэо Хедер (Theo Haerder) и Андреас Рютер (Andreas Reuter), опубликовали обзор, описывающий поддержание целостности базы данных в параллельно изменяемой среде. Они объединили требования в четыре правила, названные атомарность (atomicity), согласованность (consistency), изолированность (isolation) и устойчивость (durability) - аббревиатура ACID[87]. В течение последующих лет концепция ACID стала эталоном для реализации транзакций в системах баз данных.

Атомарность

Транзакция (называемая также единицей работы) описывается как множество действий, преобразующих данные. Чтобы быть "атомарной", транзакция должна быть реализована таким образом, чтобы обеспечить принцип "все или ничего, когда выполняются либо все операции, либо ни одна из них"[88]. Транзакция либо завершается полностью (подтверждается, commit), либо отменяется (откатывается, rollback).

Согласованность

Предполагается, что транзакции выполняют корректные преобразования состояния абстрактной системы - т. е. база данных должна оставаться в согласованном состоянии после завершения транзакции, независимо от того, была ли она подтверждена или отменена. Концепция транзакции предполагает, что программисты имеют механизм, позволяющий им объявлять и проверять правила согласованности. Стандарты SQL для реализации этих механизмов на сервере предоставляют триггеры, ограничения ссылочной целостности и ограничения CHECK.

Изолированность

В то время как транзакция изменяет совместно используемые данные, система должна создать для каждой транзакции иллюзию, что она выполняется изолированно; ей

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

В главе 26 рассматриваются три уровня изоляции транзакций, реализованные в Firebird вместе со средствами реагирования на конфликты и предотвращения работы транзакции, которая накладывалась бы на работу другой транзакции.

Устойчивость

Когда транзакция завершается, ее изменения должны быть устойчивыми - т. е. новое состояние всех объектов, видимых другим транзакциям после подтверждения, будет сохранено и будет постоянным, независимо от наличия ошибок в оборудовании или краха программного обеспечения.

вернуться

87

Theo Haerder and Andreas Reuter, "Principles of Transaction-Oriented Database Recovery", ACM Computing Surveys 15(4) (1983): 287-317.

вернуться

88

Andreas Reuter and Jim Gray, Transaction Processing Concepts and Techniques (San Francisco, С A: Morgan Kaufmann, 1993).