Шрифт:
Интервал:
Закладка:
<предложение-резервирования> : := <таблица> [, <та&лица> ...] [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
Режим разрешения блокировок
WAIT
isc_tpb_wait
NO WAIT
isc_tpb_nowait
Версия записи
RECORD_VERSION
isc_rec version
NO RECORD_VERSION
isc_no_rec_version
Резервирование таблиц
SHARED
isc_tpb_shared
PROTECTED
isc_tpb_protected
READ
isc_tpb_lock_read
WRITE
isc_tpb_lock_write
Нет эквивалента SQL
Отключает протокол автоотмены
isc_tpb_no auto undo
Протокол автоотменыПо умолчанию сервер поддерживает в памяти протокол внутренних точек сохранения (internal savepoint log) для добавляемых и изменяемых строк. При нормальном течении процесса записи протокола удаляются при каждом подтверждении или откате транзакции. Однако при некоторых условиях система отказывается от протокола и напрямую обращается к глобальному образу состояния транзакции (TSB). Такой переход обычно происходит, когда отменится очень большое количество добавлений или транзакция, использующая множество пользовательских точек сохранения (см. разд. "Вложенные транзакции"), исчерпает возможности этого протокола.
Приложение может отключить использование в транзакции этого протокола автоотмены, передав константу isc_tpb_no_auto_undo в TPB.
Доступ к идентификатору транзакции
Начиная с Firebird 1.5 идентификатор (TID) текущей транзакции (который получается из хранимых данных состояния транзакции) доступен в виде контекстной переменной. Он доступен в DSQL, isql, триггерах и хранимых процедурах. Это переменная CURRENT_TRANSACTION.
Например, для получения идентификатора в запросе вы можете выполнить следующее:
SELECT CURRENT_TRANSACTION AS TRAN_ID FROM RDВ$DATABASE;
Для сохранения его в таблице нужно выполнить:
INSERT INTO TASK_LOG (USER_NAME, TRAN_ID, START_TIMESTAMP)
VALUES (CURRENT_USER, CURRENT_TRANSACTION, CURRENT_TIMESTAMP) ;
! ! !
ВНИМАНИЕ! Идентификаторы транзакции не являются достаточно стабильными, чтобы их использовать в качестве ключей. Серия номеров для идентификаторов транзакций будет устанавливаться в 1 каждый раз при восстановлении базы данных.
. ! .
Firebird 1.0.x не предоставляет механизма отслеживания транзакций.
Использование TID в приложениях
Идентификатор транзакции на сервере не является тем же самым, что и дескриптор транзакции, который клиент Firebird получает в свое приложение. Довольно обоснованным является ассоциирование идентификатора транзакции с дескриптором транзакции при условии, что вы помните о необходимости изменить отношение между идентификатором и дескриптором транзакции при новой инициализации дескриптора. Каждое использование дескриптора в вашем приложении должно быть атомарным.
Идентификатор транзакции может быть полезным при отслеживании приложений и пользователей, ответственных за долгие транзакции в системе, ухудшающие ее производительность. Служебная программа циклического отслеживания может записывать на сервер время старта и завершения транзакций (подтверждение или отмена). В частности, отсутствие времени завершения будет полезным для отыскания пользователей, привычно использующих кнопку "восстановить" для завершения задач, или приложений, в которых регулярно происходит отказ при подтверждении работы.
Процесс выполнения транзакции
- Delphi. Учимся на примерах - Сергей Парижский - Программирование
- Сделай видеоигру один и не свихнись - Слава Грис - Программирование / Руководства
- Психбольница в руках пациентов - Алан Купер - Программирование