Работа с транзакциями. Кэширование изменений.

Цель работы: научится создавать кэш и управлять им; грамотно использовать свойства, события и методы компонентов для работы с транзакциями и кэшем; научится создавать транзакции и управлять ими.

Ø Реализация механизма транзакций

Механизм транзакций используется для поддержания целостности БД: транзакция переводит БД из одного целостного состояния в другое. Транзакция может быть явной и неявной. Неявная транзакция запускается и завершается автоматически, явной транзакцией управляет программист. Для модификации данных в удаленной базе может использоваться SQL-запрос, выполняемый с помощью метода ExecSQL компонента Query. Такой запрос называют PassThrough SQL, его выполнение приводит к запуску неявной транзакции. Способ взаимодействия с сервером на уровне такой транзакции определяет параметр sqlpassthru mode псевдонима БД или драйвера InterBase, который может принимать следующие значения:

1. shared autocommit — операторами модификации БД, например, update или insert, автоматически запускается неявная транзакция (по умолчанию); после внесения изменений эта транзакция автоматически подтверждается; разные транзакции могут использовать общее соединение с БД;

2. shared no autocommit — операторами модификации БД также автоматически запускается неявная транзакция, но автоматического ее подтверждения не происходит, и нужно самостоятельно выполнять оператор commit; разные транзакции могут использовать общее соединение с БД;

3. not shared — транзакции должны использовать различные соединения с БД и подтверждаться выполнением оператора commit. Возможность явного управления транзакциями предоставляет язык SQL сервера, который имеет в своем составе следующие операторы:

ü set transaction — начать транзакцию;

ü commit — подтвердить транзакцию;

ü rollback — отменить транзакцию.

Оператор запуска явной транзакции имеет формат:

SET TRANSACTION

[READ WRITE | READ ONLY]

[WAIT | NO WAIT]

[[ISOLATION LEVEL]

{SNAPSHOT [TABLE STABILITY] | READ COMMITED}]

[RESERVING <Список таблиц>

[FOR [{SHARED | PROTECTED}]

[{READ | WRITE}]];

Все операнды этого оператора являются необязательными и позволяют управлять перечисленными ниже режимами транзакции. Режим доступа к данным:

read write — разрешены чтение и модификация записей (по умолчанию);

read only — разрешено только чтение записей.

Поведение в случае конфликта транзакций при обновлении записей:

wait — ожидание завершения другой транзакции (по умолчанию);

no wait — прекращение данной транзакции.

Уровень изоляции от других транзакций (операнд isolation level):

snapshot — чтение данных в состоянии на момент начала транзакции (по умолчанию); изменения, сделанные другими транзакциями, в данной транзакции не видны;

snapshot table stability — предоставление транзакции исключительного доступа к таблицам; другие транзакции могут читать записи из таблиц;

read commited — чтение только подтвержденных изменений в записях; если изменения еще не подтверждены, то читается предыдущая версия записи.

Блокирование таблиц, указанных в списке операнда reserving, для других транзакций:

protected read — разрешено только чтение записей;

protected write — для транзакций с уровнем изоляции snapshot или read committed разрешено только чтение записей;

shared read — разрешены чтение и модификация записей;

shared write — разрешено чтение записей;

Для транзакций с уровнем изоляции snapshot или read committed разрешена модификация записей. Действие операторов commit и rollback по утверждению и отмене транзакции аналогично действию одноименных методов компонента Database.

Ø Использование механизма кэшированных изменений

Механизм кэшированных изменений заключается в том, что на компьютере клиента в кэше (буфере) создается локальная копия данных, и все изменения в данных выполняются в этой копии. Для хранения локальной копии используется специальный буфер (кэш). Сделанные изменения можно утвердить, перенеся их в основную БД, хранящуюся на сервере, или отказаться от них. Этот механизм напоминает механизм транзакций, но, в отличие от него, снижает нагрузку на сеть, т. к. все изменения передаются в основную БД одним пакетом. Механизм кэшированных изменений реализуется в приложении, для чего компоненты, в первую очередь Database, Table и Query, имеют соответствующие средства. Кроме того, механизм кэшированных изменений поддерживается предназначенным для этого компонентом UpdateSQL. Основные достоинства рассматриваемого механизма проявляются для удаленных БД, но его можно использовать и при работе с локальными БД.

Пример использования компонента T IB Update SQL (с использованием TIBTable и TIBQuery):

Свойство CachedUpdates у TIBTable и TIBQuery следует выставить в значение True. При этом они должны быть неактивными. Затем в TIBQuery в свойстве UpdateObject нужно указать наш TIBUpdateSQL. Затем в TIBQuery прописать запрос, например:

select *

from RENT

where RN > 100;

и активизировать TIBQuery и TIBTable. После этого на какую-нибудь кнопку на форме пропишем код принятия изменений, например:

 

procedure TForm1.Button3Click(Sender: TObject);

begin

try

IBDatabase1.ApplyUpdates([TRENT, IBQuery1]); // применить обновления

except // если возникла ошибка

MessageBox(Handle, 'Изменения не сохранены', 'Error', MB_ICONERROR);

TRENT.CancelUpdates; // отменить обновления

IBQuery1.CancelUpdates; // отменить обновления

end;

end;


ЛАБОРАТОРНАЯ №10

Обеспечение достоверности данных, исключительные ситуации.

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

Исключения — механизм сообщения об ошибках, которые возникают в процессе исполнения хранимых процедур и триггеров.

Исключение создают командой Database->New Exception:

Примечание Длина сообщения не должна превышать 78 символов.

Для генерации исключения в процедуре или триггере используют команду: EXCEPTION ИмяИсключения, например:

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

Когда исключение сгенерировано:

· завершается процедура (триггер), в которой оно было возбуждено, и отменяются все действия, которые были ею выполнены непосредственно или косвенно;

· возвращается сообщение об ошибке в вызывающее приложение;

· его можно обработать командой when. Если оно обрабатывается, то его проведение отличается от выше описанного.

При использовании процедур на обновление данных одной записи таблицы требуется знать код этой записи (для задания условия поиска в update … set … = … where [условие]), который можно передавать как параметр этой процедуры, например:

create procedure UPDATE_RN (sel_id char(20), n_rn numeric(6,2))

as

begin

if (:n_rn <= 0) then

exception impossible_rn;

else

update rent

set rn = :n_rn

where TYP = :sel_id;

end

где sel_id – это код изменяемой записи, а n_rn – новое значение для записи.

В Delphi-приложении запустить процедуру и задать эти параметры можно следующим способом (используя компонент TIBStoredProc):

try

IBStoredProc1.StoredProcName := 'UPDATE_RN'; // имя процедуры

IBStoredProc1.ParamByName('SEL_ID').AsString :=

TRENT.Fields.Fields[0].AsString; // ключевое поле (индекс может быть другим)

IBStoredProc1.ParamByName('N_RN').AsInteger :=

StrToInt(Edit1.Text); // новое значение (например, вводится через TEdit)

IBStoredProc1.Prepare; // подготовка процедуры к запуску

IBStoredProc1.ExecProc; // запуск процедуры

finally

// здесь можно прописать код для неудачного запуска процедуры или возникновения исключения

end;

TRENT.Refresh;

Для перехвата исключительной ситуации код следует поместить в блок try..finally.

Лабораторная №11

Работа с отчетами.

Цель работы: научится форматировать отчеты.

Для создания простого отчета в формате txt можно использовать класс TStringList для формирования и сохранения отчета в файл. Для работы с этим классом сначала его нужно создать, а при завершении работы с ним - удалить из памяти, далее пример:

var

S : TStringList;

begin

S := TStringList.Create; // создание экземпляра класса

S.Free; // уничтожение экземпляра класса

end;

Для формирования отчета будем проходить по всем записям таблиц и выводить их в удобочитаемом формате в отчет (сначала в S : TStringList, затем из него в файл report.txt).

procedure TForm1.Button4Click(Sender: TObject);

var

s : TStringList;

begin

s := TStringList.Create;

// таблица OWNER

TOWNER.First;

while not TOWNER.Eof do

begin

s.Add(TOWNER.Fields.Fields[0].AsString + ' ' +

TOWNER.Fields.Fields[1].AsString + ' ' +

TOWNER.Fields.Fields[2].AsString);

// таблица LEASE

TLEASE.First;

while not TLEASE.Eof do

begin

s.Add (#9+TLEASE.Fields.Fields[0].AsString + ' ' +

TLEASE.Fields.Fields[1].AsString + ' ' +

TLEASE.Fields.Fields[2].AsString + ' ' +

TLEASE.Fields.Fields[4].AsString + ' ' +

TLEASE.Fields.Fields[5].AsString );

// таблица REALTY

TREALTY.First;

while not TREALTY.Eof do

begin

s.Add (#9#9+TREALTY.Fields.Fields[1].AsString);

// таблица RENT

TRENT.First;

while not TRENT.Eof do

begin

s.Add(#9#9#9+TRENT.Fields.Fields[1].AsString);

TRENT.Next;

end;

s.Add(#13#10);

TREALTY.Next;

end;

s.Add(#13#10);

TLEASE.Next;

end;

s.Add('----------------------------------------------------');

TOWNER.Next;

end;

// сохранение сформированного отчета в файл

s.SaveToFile('report.txt');

s.Free;

end;


ЛАБОРАТОРНАЯ №12