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

Заголовочный файл API, ibase.h, объявляет прототипы функций, определения типов для каждой структуры, определения параметров и макросы, которые используются в функциях. Он поставляется в каталоге Firebird /include.

Для некоторых объектно-ориентированных сред разработки, таких как Object Pascal, Borland C++ Builder, Java, PHP, Python и DBI::Perl классы и компоненты полностью инкапсулируют вызовы API Firebird, относящиеся к транзакциям. Пользовательские драйверы для интерфейсов соединения со стандартными базами данных SQL - в особенности ODBC, JDBC и .NET- похожим образом представляют API[101].

Запуск транзакции

SQL

Оператор SQL для запуска транзакции имеет следующий синтаксис:

SET TRANSACTION [NAME <имя-транзакции>]

[READ WRITE | READ ONLY] /* режим доступа */

[WAIT | NO WAIT] /* режим разрешения блокировок */

[ISOLATION LEVEL] /* уровень изоляции */

{SNAPSHOT [TABLE STABILITY] | READ COMMITTED [[NO] RECORD VERSION]}

[RESERVING <предложение-резервирования>

| USING <дескриптор-базы-данных> [,дескриптор-базы-данных...]];

Финальное предложение RESERVING задает необязательное резервирование таблиц, обсуждавшееся в предыдущей главе. Его синтаксис представляется в виде:

<предложение-резервирования> : := <таблица> [, <та&лица> ...] [FOR [SHARED | PROTECTED] {READ | WRITE}]

[, <предложение-резервирования> [, <предложение-резервирования> ...]]

! ! !

ПРИМЕЧАНИЕ. Необязательное имя транзакции - объявляемое в приложении и указываемое в предложении SET TRANSACTION - недоступно нигде, кроме ESQL.

. ! .

Вы можете проверить этот оператор в isql. Откройте базу данных employee.fdb и запустите новую транзакцию следующим образом:

SQL> COMMIT;

SQL> SET TRANSACTION READ WRITE ISOLATION LEVEL SNAPSHOT TABLE STABILITY;

SQL> SELECT EMP_NO, FIRST_NAME, LAST_NAME

CON> FROM EMPLOYEE WHERE FIRST_NAME = 'Robert';

EMP NO FIRST NAME LAST NAME

==========================

2 Robert Nelson

SQL>

! ! !

СОВЕТ. Ключевые слова ISOLATION LEVEL являются необязательными, READ WRITE и WAIT являются значениями по умолчанию и могут быть опущены, если не требуются другие значения.

. ! .

Затем откройте другое окно командной строки и запустите isql или другой инструмент, который позволит вам конфигурировать тарнзакции, и запустите другую транзакцию чтения/записи для той же базы данных:

SQL> COMMIT;

SQL> SET TRANSACTION READ WRITE NOWAIT SNAPSHOT;

Теперь через тот же интерфейс попытайтесь изменить любую строку в базе данных tmployee.fdb:

SQL> UPDATE EMPLOYEE SET FIRST_NAME = 'Dodger'

SQL> WHERE FIRST_NAME = 'Roger';

ISC ERROR CODE:335544345

lock coflict on no wait transaction (конфликт блокировки для транзакции, не являющейся ожидаемой)

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

Транзакция по умолчанию

Следующий оператор также допустим:

SQL> COMMIT;

SQL> SET TRANSACTION;

Он запускает транзакцию, как и большинство операторов, с конфигурацией по умолчанию, что эквивалентно:

SQL> COMMIT;

SQL> SET TRANSACTION READ WRITE WAIT SNAPSHOT;

! ! !

ПРИМЕЧАНИЕ. Существует еще "транзакция по умолчанию", которая используется в клиентах ESQL для сконфигурированной единой транзакции, определенной на сервере и клиенте константой gds trans. Клиент ESQL стартует эту транзакцию автоматически, если он передает оператор запроса, а перед этим никакая транзакция явно не запускалась.

. ! .

API

Функция API, которая выполняет эквивалентную работу, называется isc_start_transaction()[102]

Запуск каждой транзакции имеет три части:

1. Создание (при необходимости) и инициализация дескриптора транзакции.

2. Создание (при необходимости) и заполнение буфера параметров транзакции (Transaction Parameter Buffer, TPB) для хранения данных конфигурации. Это не обязательно.

3. вызов isc_start_transaction().

При отсутствии необязательного TPB клиент запускает транзакцию точно так же, как и транзакцию по умолчанию, которая стартует при выдаче оператора SET TRANSACTION.

Дескриптор транзакции

Каждый раз, когда вы собираетесь вызвать эту функцию, вы должны иметь переменную, длинный указатель - называемую дескриптором транзакции - уже объявленную в вашем приложении и инициализированную нулем[103]. Приложение должно иметь один дескриптор транзакции для каждой конкурирующей транзакции, вы также можете повторно использовать дескрипторы, заново проинициализировав их.

Дескриптор транзакции должен быть установлен в ноль при его инициализации до запуска транзакции. Транзакция завершится с ошибкой, если ей будет передан ненулевой дескриптор.

Буфер параметров транзакции

TPB является байтовым массивом (или вектором) констант, каждая из которых представляет параметр транзакции и начинается с префикса isc_tpb_. Первым параметром всегда является константа isc_tpb_version3, которая определяет версию структуры TPB[104]. Все последующие элементы массива являются константами, которые представляют эквивалентные SQL атрибуты транзакции.

В табл. 27.1 показаны параметры транзакции SQL и эквивалентные им константы TPB.

Типичное объявление TPB в языке С выглядит следующим образом:

static char isc_tpb[] =

{

isc_tpb_version3,

isc_tpb_write,

isc_tpb_wait,

isc_read_committed,

isc_tpb_no_rec_version

};

Этот TPB по своему действию идентичен следующему:

SET TRANSACTION READ WRITE WAIT READ COMMITTED NO RECORD_VERSION;

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

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

Таблица 27.1. Атрибуты транзакции и эквивалентные константы TPB

Тип атрибута

Атрибут SQL

Константа TPB

Режим доступа

READ ONLY

isc_tpb_read

READ WRITE

isc_tpb_write

Уровень изоляции

READ COMMITTED

isc_tpb_read committed

SNAPSHOT

isc_tpb_concurrency

SNAPSHOT TABLE STABILITY

isc_tpb_consistency

вернуться

101

Для большинства этих реализаций была выполнена трансляция заголовочного файла С Firebird в соответствующий язык высокого уровня для предоставления средств API Firebird (или InterBase) для этого языка. Если вы планируете разрабатывать программы с использованием API, хорошим решением будет поиск в Интернете существующих трансляций заголовочного файла.

вернуться

102

Фактически существуют две различные функции для запуска транзакции: isc_start_ transaction() используется в языках, которые поддерживают передачу переменного количества аргументов при вызове функций; isc_start_multiple() используется в языках, требующих статический список аргументов. isc_start_transaction() ограничивается одной транзакцией, которая может использовать до 16 баз данных, в то время как isc_start_multiple О запускает транзакции, обращающиеся к большему количеству баз данных или обращающиеся к переменному количеству баз данных, которое может превышать 16.

вернуться

103

Тип isc_tr_handle является указателем void, определенным в заголовочном файле ibase.h, который расположен в каталоге /include в каталоге вашей инсталляции Firebird.

вернуться

104

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