На этом шаге мы рассмотрим компонент TIBTransaction.
Для установления связи с InterBase в технологии IBX хотя бы один компонент TIBTransaction должен быть связан с компонентом TIBDatabase. В многозвенных приложениях каждый SQL-запрос исполняется в отдельной транзакции. Свойства компонента TIBTransaction перечислены в таблице 1.
Свойство | Описание |
---|---|
property Active: Boolean; | Содержит True, если компонент активен |
property DatabaseCount: Integer; | Содержит количество БД, обслуживаемых в данной транзакции |
property Databases [Index : Integer]:TIBDatabase; | Дает индексный доступ к БД, обслуживаемым транзакцией |
type TTransactionAction = (taRollback, taCommit, taRollbackRetaining, taCoramitRetaining); propertyDefaultAction: TTransactionAction; |
Указывает способ завершения транзакции по истечении времени, заданного в свойстве IdleTimer:
|
property DefaultDatabase: TIBDatabase; | Содержит текущую БД |
property Handle: TISC_TR_HANDLE; | Содержит дескриптор транзакции |
property HandleIsShared: Boolean; | Содержит True, если дескриптор транзакции разделяемый |
property IdleTimer: Integer; | Указывает, сколько времени в миллисекундах должно пройти перед автоматическим выполнением свойства DefaultAction |
property InTransaction: Boolean; | Указывает, находится ли БД в состоянии незавершенной транзакции |
property Params: TStrings; | Содержит набор параметров для компонента |
property SQLObjectCount: Integer; | Содержит количество обслуживаемых транзакцией активных SQL-компонентов (наборов данных, IBSQL, BLOB) |
property SQLObjects [Index: Integer]:TIBBase; | Открывает индексный доступ к обслуживаемым транзакцией SQL-компонентам |
property TPB: PChar; | Содержит ссылку на буфер параметров транзакции (только в режиме чтения). Для записи параметров служит свойство Params |
property TPBLength: Short; | Указывает длину буфера параметров компонента |
Методы компонента TIBTransaction перечислены в таблице 2.
Метод | Описание |
---|---|
function AddDatabase (db: TIBDatabase) : Integer; | Добавляет к компоненту новый компонент TIBDatabase |
procedure СhecкDatabasesInList; | Проверяет список связанных компонентов TIBDatabase. Если список пуст, возбуждается исключение |
procedure CheckInTransaction; | Проверяет активность транзакции и список обслуживаемых ею компонентов TIBDatabase. Если транзакция неактивна или список пуст, возбуждается исключение |
Procedure CheckNotInTransaction; | Проверяет активность транзакции и список обслуживаемых ею компонентов TIBDatabase. Если транзакция активна или список не пуст, возбуждается исключение |
procedure Commit; | Подтверждает текущую транзакцию и завершает ее |
procedure CommitRetaining; | Аналогичен методу Commit, но сохраняет контекст транзакции |
function FindDatabase (db: TIBDatabase) : Integer; | Возвращает индекс связанного компонента TIBDatabase |
procedure RemoveDatabase (Idx: Integer); | Удаляет компонент TIBDatabase с индексом Idx из списка связанных с компонентом TIBTransaction |
procedure RemoveDatabases; | Удаляет все компоненты TIBDatabase из списка связанных с компонентом TIBTransaction |
procedure Rollback; | Осуществляет откат текущей транзакции |
procedure RollbackRetaining; | Аналогичен методу Rollback, но сохраняет контекст транзакции |
procedure StartTransaction; | Начинает очередную транзакцию |
В момент открытия компонента TIBTransation автоматически стартует связаная с ним транзакция. Пример неправильного кода:
procedure TForm1.FormActivate(Sender: TObject); begin with DataModule2 do begin Nakls.Open; IbTransaction1.StartTransaction; // Ошибка! // Транзакция уже стартовала ! end; end;
В момент открытия НД Nakls автоматически открывается и компонент IBTransаiction1, поэтому второй оператор пытается открыть вложенную транзакцию, что недопустимо. В листинге 1 приводится правильное решение классической задачи перевода денег с дебиторского счета на кредиторский.
uses Unit2, DB; {$R *.DFM} procedure TForm1.btnChangeClick(Sender: TObject); var Delta: Currency; begin try // Проверяем правильность записи суммы перевода Delta := StrToFloat(Edit1.Text) ; except Edit1.SelectAll; Edit1.SetFocus; Exit; end; with DM do begin // Сумма перевода не может превышать сумму на счету дебитора: if tbDebitSumm.Value>Delta then begin try // Снимаем с дебиторского счета vtbDebit.Edit; tbDebitSumm.Value := tbDebitSumm.Value-Delta; tbDebit.Post; // Начисляем на кредиторский счет tbCredit.Edit; tbCreditSumm.Value := tbCreditSumm.Value+Delta; tbCredit.Post; // Ошибок нет - подтверждение транзакции IBTransaction1.CommitRetaining; except // Ошибка - откат транзакции ShowMessage('Операция не прошла!'); IBTransaction1.RollbackRetaining; еnd; // try end // if tbDebitSumm.Value>Delta else Edit1.SelectAll; end; // with DM Editl.SetFocus; end; procedure TForm1.FormActivate (Sender: TObject); begin Editl.SetFocus; end;
Для подтверждения/отката транзакции используются методы CommitRetaining и RollbackRetaining компонента. Они выполняют те же действия, что и методы Commit и Rollback, но в отличие от последних не завершают транзакцию и, следовательно, не закрывают связанные с ней НД. С компонентом связано единственное событие, которое возникает после завершения транзакции по истечении времени, указанного в свойстве IdleTimer:
property OnIdleTimer: TNotifyEvent;
На следующем шаге мы рассмотрим компонент TIBTable.