- •Acid-свойства транзакций
- •Проблемы параллельной работы транзакций
- •Потерянное обновление
- •«Грязное» чтение
- •Неповторяющееся чтение
- •Собственно несовместимый анализ
- •Конфликты между транзакциями
- •Реализация изолированности транзакций средствами sql Уровни изоляции
- •Поведение при различных уровнях изолированности
- •Режимы транзакций сервера ib
- •Уровень изоляции snapshot
- •Уровень изоляции snapshot table stability
- •Уровень изоляции read committed record_version
- •Уровень изоляции read committed no record_version
- •Взаимодействие транзакций
- •Режимы блокировки (ожидания) wait и no wait
- •Использование компонентов ib Express Компонент tibTransaction
- •Явные транзакции в ibx
- •Использование таймера и действия по умолчанию
- •Использование CachedUpdates
- •Работа с транзакциями в примере MastApp, поставляемом с Delphi 5.0
Использование компонентов ib Express Компонент tibTransaction
При использовании IB Express все транзакции контролируются компонентом TIBTransaction. Он содержит следующие ключевые свойства:
Params
DefaultAction
IdleTimer
а также методы:
StartTransaction
Commit
CommitRetaining
Rollback
RollbackRetaining
Режим, в котором запускается транзакция, указывается в свойстве Params в виде списка символьных строк. Каждая опция режима указывается на отдельной строке, запятые не нужны. Опции транзакции можно подробнее посмотреть в IB API Guide.
Режим доступа:
isc_tpb_write - READ WRITE
isc_tpb_read - READ ONLY
Режим ожидания:
isc_tpb_nowait - NO WAIT
isc_tpb_wait - WAIT
Уровень изоляции:
isc_tpb_read_committed, isc_tpb_no_rec_version - READ COMMITTED NO RECORD_VERSION
isc_tpb_read_committed, isc_tpb_rec_version - READ COMMITTED RECORD_VERSION
isc_tpb_concurrency - SNAPSHOT
isc_tpb_consistency - SNAPSHOT TABLE STABILITY
Параметр isc_tpb_version3, как того требует API Guide, указывать не нужно.
Посмотреть, является ли транзакция активной, можно с помощью свойства Active или с помощью метода InTransaction - в обоих случаях вызывается один и тот же метод GetInTransaction.
Действие по умолчанию, выполняемое при завершении транзакции, устанавливается свойством DefaultAction. По умолчанию DefaultAction=TACommit, то есть изменения подтверждаются и курсор закрывается.
Свойство IdleTimer определяет временной интервал в миллисекундах, по истечении которого будет производиться автоматическое завершение транзакции согласно свойству DefaultAction. Для создания таймера используется компонент типа TTimer и при значении IdleTimer=0 действие по умолчанию не выполнится ни разу.
Неявные транзакции в IBX
Если явно не вызывать TIBTransaction.StartTransaction, а просто открыть набор данных, подключенный к TIBTransaction, (например TIBTable) начнется неявная, с точки зрения клиентской программы, транзакция. К сожалению, неявную транзакцию можно только подтвердить (COMMIT), и нельзя откатить (ROLLBACK).
Дело в том, что при открытии набора данных IBX проверяет, активна ли транзакция, ассоциированная с набором данных, и если нет - стартует ее автоматически, выставляя при этом внутренний флаг набора данных FDidActivate:=True. Закрыть набор данных можно двумя способами: вызвать TIBCustomDataSet.Close, что приведет и к закрытию неявной транзакции, либо вызвать напрямую один из методов TIBTransaction, которые, завершив транзакцию, закроют и набор данных (кроме CommitRetaining).
При закрытии набора данных по Close выполняется:
if FDidActivate then DeactivateTransaction;
и далее в методе DeactivateTransaction:
if Transaction.InTransaction then Transaction.Commit;
При завершении транзакции методом TIBTransaction.Commit или TIBTransaction.Rollback происходит следующее. В методе TIBTransaction.EndTransaction выполняются завершающие действия для объектов, ассоциированных с транзакцией:
for i := 0 to FSQLObjects.Count - 1 do if FSQLObjects[i] <> nil then SQLObjects[i].DoBeforeTransactionEnd;
В методе TIBCustomDataSet.DoBeforeTransactionEnd выполняется
if Active then Active := False;
После этого в методе TIBCustomDataSet.InternalClose выполняется закрытие набора данных, описанное выше:
if FDidActivate then DeactivateTransaction;
и далее:
if Transaction.InTransaction then Transaction.Commit;
Таким образом, текущая реализация неявных транзакций такова, что они всегда подтверждаются.