
Ю. А. Григорьев, Г. И. Ревунков - Банки данных
.pdf12. Логическое проектирование систем распределенной обработки данных
|
Сегмент отката |
|
|
|
(одна транзакция для |
|
|
|
каждого процесса) |
Запись «после |
Программа 2 |
Программа 1 |
|
||
|
обновления» |
||
(процесс 1) |
|
|
(процесс 2) |
UPDATE- |
|
|
|
COMMIT-
Журнал
транзакций (диск 1)
Записи «после
обновления»
Журнал
транзакций (диск 2)
Архивация журнала
Диск, лента, магнитооптическое устройство
Рис. 12.23. Схема ведения транзакций
1. Транзакция из сегмента отката переписывается в журнал транзак ций. Переписываются записи после изменения (см. 1 на рис. 12,23). Если до этого активным являлся журнал транзакций на диске 2 и он полностью за полнен (журнал имеет фиксированный размер на диске), то СУБД автома тически переключается на журнал транзакций, размещенный на диске 1. Теперь на нем будут сохраняться записи транзакций «после обновления». При этом журнал на диске 2 будет автоматически архивироваться сервером СУБД на устройство высокой емкости. После архивирования журнал осво бождается для приема записей транзакций (после переполнения журнала на диске 7), и т.д.
2. Записи БД «после обновления» запоминаются в таблицах БД (через буфер сервера СУБД), т.е. СУБД показывает изменения другим процессам.
240
|
12.2. Разработка пргтоэюений |
|
|
Сегмент отката |
|
Откат |
> |
Начало |
|
|
IDJIOIDI |
сегмента |
|
Начало файла журнала
Журнал транзакций
Докат ^
• |
• |
Отметки о перезаписи измененных блоков из буфера сервера СУБД на диск с БД
Полные транзакции
Неполная транзакция
Рис. 12.24. Схема восстановления данных в БД после сбоя
Необходимо отметить, что транзакция процесса 7 удаляется из сегмента отката не сразу после выполнения команды COMMIT. Это связано с использо ванием в Oracle версий записей. Пусть оператор SELECT (см. процесс 2) пыта ется читать запись, обновленную процессом 1. Если дата (время) обновления записи (дата выполнения COMMIT) позже даты начала выполнения SELECT, то запись «до обновления» читается из сегмента отката (см. 3 на рис. 12.23). Это связано с тем, что по SELECT уже могли быть прочитаны из БД другие записи той же транзакции, но до того как они были обновлены в БД. Чтобы сохранить целостность поиска (т.е. чтобы не было рассогласования), используется старая версия записи («до обновления»). Если дата обновления записи раньше даты начала выполнения SELECT, то читается запись из БД (см. 4 на рис. 12.23). Транзакция удаляется в сегменте отката (т.е. освобождается память в этом сег менте) в том случае, если сервером СУБД выполнены все команды, которые были начаты до завершения этой транзакции.
Рассмотрим, как СУБД восстанавливает данные в БД после сбоев или отказов (рис. 12.24). В сервере СУБД через определенный интервал времени
241
12. Логическое проектирование систем распределенной обработки данных
запускается процесс, перезаписывающий измененные блоки из буфера сер вера СУБД на диск. После этого в журнале транзакций делается соответст вующая отметка. Предположим, что система «зависла» в момент перезаписи транзакции из сегмента отката в журнал транзакции (см. «неполная тран закция» на рис. 12.24). Это один из самых неприятных случаев. После вос становления и перезагрузки системы СУБД автоматически пытается восста новить потерянные данные и целостность БД.
1. СУБД находит в журнале транзакций последнюю (с конца файла журнала) отметку о перезаписи данных на диск и выполняет докат базы данных (см. рис. 12.24), т.е. начиная с этой отметки и до конца файла, СУБД читает из журнала транзакций записи после изменений и записывает их в БД (через буфер сервера СУБД). При этом в БД помещаются записи после изменений и из неполной транзакции.
2. СУБД выполняет откат БД, чтобы устранить изменения, вызванные восстановлением неполной транзакции. Для этого СУБД читает с конца и до начала сегмента отката записи «до обновления» и записывает их в БД, уст раняя тем самым нежелательные изменения.
Обработка тупиковых ситуаций. Рассмотрим следующий пример. Предположим, что процедура «проводка», рассмотренная выше при обсуж дении вопроса о блокировках, теперь выглядит следующим образом:
CREATE PROCEDURE (noMepi IN NUMBER, номерз IN NUMBER,
BEGIN |
сумма IN NUMBER) IS |
|
|
UPDATE |
счет SET остаток=остаток - сумма |
WHERE |
номер=номерi; |
UPDATE |
счет SET остаток=остаток + сумма |
WHERE |
номер=номер2; |
END; |
|
Тупиковая ситуация возникает при одновременном обращении рабо чих станций к процедуре «проводка». В данном случае СУБД выполнит откат транзакции процесса с наименьшим приоритетом и выдаст этому про цессу сообщение об ошибке.
В прикладной программе должны быть закодированы операторы распо знавания ошибок. В PL/SQL для этого целей используется блок EXCEPTION:
EXCEPTION
- если транзакция была прервана СУБД WHEN TRANSACTION^BACKED^OUT обработка ошибки;
WHEN идентификатор другой ошибки обработка ошибки;
END;
242
12.2. Разработка прилоэюений
File Edit Option |
|
|
|
|
|
|
|
CASE*Dictionary |
|
Module Definition |
|
Page 1 of 3 |
|||
Appl. SECURITES Version 1 Owns Module ? Yes |
|
28-OCT-96 |
|||||
|
STEVE |
AQ |
|||||
|
|
|
|
|
|
|
|
Short Name |
|
HAGGLE |
|
|
Contains Sub-mods? |
N |
|
Module Name |
|
Результаты торгов |
Used by Super-mods? |
N |
|||
Purpose |
|
Отобразить результаты торгов по ценным бумагам |
|
||||
Language |
Type |
Format |
Complexity |
Invoked |
Size |
|
|
SQL*FORMS |
|
SCREEN |
|
EASY |
|
|
|
Source Path
Runtime Path
Command Line iap <MODULE> <UN>/<PW>
Titles
-Top |
|
|
-Bottom |
|
|
-Short Haggle |
|
|
Define Module Group Access ? |
Define Data Usage ? |
Y |
Enter 'Y' to jump to Data Usage Screen |
|
|
Count: *1 |
|
<Replace> |
Рис. 12.25. Окно Module Definition
Пример генерации приложений с помощью CASE'^Generator.
Продолжим рассмотрение примеров, приведенных в параграфах 10.3, 11.2 и 12.1, где были разработаны диаграмма потоков данных, концептуальная и логическая схемы БД. Ниже приводится описание модуля «Результаты торгов».
1. Перед проектированием нового модуля приложения необходимо зарегистрировать его имя в хранилище CASE*Dictionary (Oracle). Для этого выберите пункт Design/Module Design/Module Definition утилиты CASE*Dictionary. На экране появится форма Module Definition (рис. 12.25). Заполните поля этого окна для модуля «Результаты торгов», включая со кращенное и полное имя нового модуля, а также его тип, формат и слож ность. Перед сохранением данных следует указать признак Y в поле Define Data Usage.
2. В результате на экране появится окно Define Data Usage (рис. 12.26), позволяющее определить более детальную информацию о поддер живаемых этим модулем данных.
243
12. Логическое проектирование систем распределенной обработки данных
File Edit Option |
|
|
|
|
|
|
|
|
|
CASE*Dictionary |
|
Module Data Usage (detailed) |
Page 1 of 3 |
|
|||||
|
|
|
|
|
|
|
28-OCT-96 |
|
|
Appl. SECURITES Version 1 |
ns Table ? YES |
|
STEVE |
AQ |
|
||||
|
|
|
|
|
|
|
|
|
|
Module Short Name HAGGLE |
CopyMDU? |
Copy FUN |
^ |
||||||
Seq |
Table/View |
TA^ |
Insert |
Select |
Update |
Delete |
Other |
|
|
4 |
SEC COU |
Table |
Y |
|
|
|
|
||
Seq |
Column |
Display |
Insert Select Update |
Delete |
Nullify |
Other |
|
||
2 |
COU_DATE |
|
Y |
|
Y |
|
|
|
|
Comment Дата торгов |
|
|
|
|
|
|
|||
4 |
COU_QUOTATION Y |
|
Y |
|
|
|
|
||
Comment Котировка ЦБ |
|
|
|
|
|
|
|||
The name of a table or view used by this module |
|
|
|
|
|||||
Count: *1 |
|
|
|
|
|
<List><Replace> |
|
Рис. 12.26. Окно Define Data Usage
С помощью окна, представленного на рис. 12.26, можно ввести ис пользуемые модулем имена таблиц и соответствующих столбцов. Можно даже задать, какие столбцы выводить на экран, какие операции выполнять над каждым столбцом, формат вывода столбца, метку каждого столбца и многое другое. Окно Define Data Usage показывает, как модуль Результаты торгов использует таблицу SECCOU (Курс продажи) и ее столбцы. Также можно описать использование столбцов таблицы SEC ISS (Эмиссия ЦБ).
3.Сохраните описание модуля Результаты торгов.
4.Теперь необходимо сгенерировать приложение. Запустите продукт CASE*Generator, введите имя пользователя и пароль и выберите пункт ме ню CASE*Generator/SQL*Forms.
5.Перед тем, как начать реализацию новой системы, необходимо за дать некоторые параметры. Выберите пункт Use Preferences. Введите имя прикладной системы (SECURITES) и номер версии. Далее в меню в центре экрана выберите U. После этого можно отредактировать параметры пользо вателя. В нижней части экрана CASE*Generator показывает продукты, для которых можно генерировать приложения. Позиционируйте курсор на CASE*Generator for SQL*Forms, version 3. Затем с помощью клавиши [Next Block] перейдите ко второй странице окна Use Preferences.
244
72.2.Разработка прилож^ений
6.Здесь следует задать только один параметр: TEMFRM, указы вающий шаблон формы для генерации приложения в SQL*Forms. Для этого с помощью клавиши [Next Block] перейдите к блоку параметров окна. CASE*Generator выведет диалог, в котором следует ввести имя параметра TEMFRM и нажать клавишу [Next Field]. После этого CASE*Generator возвращается к окну, которое содержит некоторую до полнительную информацию. Здесь просто следует стереть поле Value и с помощью клавиши [Commit] сохранить изменения. Вернитесь в меню CASE*Generator /SQL*Forms.
7.Выберите пункт CASE*Generator/SQL*Forms/CASE*Generator Utilities/DDL Command Generator. При этом CASE*Generator запускает ути литу командной строки, которая запрашивает некоторую простую инфор мацию, такую, как имя прикладной системы, номер ее версии и тип базы данных (наряду с Oracle можно генерировать приложения для DB2 фирмы IBM), а также тип генерируемого объекта (user означает генерацию таблиц, представлений, индексов, последовательностей и кластеров; dba — генера цию БД, табличных областей, сегментов отката, пользователей и полномо чий) и имя выходного файла для DDL-сценария.
8.Если DDL-сценарий вас удовлетворяет, создайте в БД Oracle соот ветствующую схему, запустив DDL-сценарий из SQL*Plus или SQL*DBA.
9.Когда все необходимые структуры готовы, выберите пункт CASE*Generator/SQL*Forms/CASE*Generator for SQL*Forms-Generate. Да лее введите имя модуля HAGGLE и нажмите клавишу [Commit]. CASE*Generator выводит окно с парой простых подсказок. В нем запраши вается количество строк, которые вы хотите выводить в каждом блоке фор мы. Для блока SEC_ISS (эмиссия ЦБ) введите 1 (это означает вывод по од ной записи о наименовании ЦБ), для блока SECCOU — 5.
10.После ввода всей необходимой информации CASE*Generator ав томатически создает приложение. После этого система запрашивает, хотите ли вы выполнить приложение. Выберите YES и система выведет окно при ложения (рис. 12.27).
Генерация описания логической схемы БД и триггеров с помо щью пакета Erwin. Продолжим рассмотрение примеров, приведенных в параграфах 11.2 и 12.1. Покажем, как с помощью пакета Erwin можно реа лизовать ссылочную целостность.
1.Выберите какую-либо связь (например, имеет), нажмите правую клавишу мыши и выберите пункт Referential Integrity. На экране появляется окно Referential Integrity. Здесь могут быть заданы требования к обработке операций INSERT, UPDATE, DELETE для родительской и дочерней сущно сти связи. Erwin предоставляет следующие варианты обработки:
•отсутствие проверки (NONE);
•проверка допустимости операции (RESTRICT);
•каскадное вьшолнение операции DELETE или UPDATE (CASCADE);
245
12. Логическое проектирование систем распределенной обработки данных
File |
Edit Option |
|
1 |
Эмиссия ЦЬ |
|
Код эмиссии ЦБ |
345789 |
|
Наименование ЦБ |
Газпром |
|
1 |
Курс продажи |
|
|
Дата торгов |
Котировка ЦБ |
03.01.971279
04.01.971300
08.01.971280
09.01.971400
13.01.971410
FRM-40400: Transaction complete - 24 records posted and committed |
|
Count: *0 |
<Replace> |
Рис. 12.27. Выходная форма программы «Результаты торгов»
• установка пустого или заданного значения по умолчанию (SET NULL или SET DEFAULT).
Всоответствии с выбранным вариантом Erwin автоматически создает триггеры на диалекте целевой СУБД (см. распечатку в конце этого пункта).
2. Проектировщик может разработать собственный триггер для какойлибо таблицы. Выберите таблицу SECCOU (курс продажи), щелкните пра вой кнопкой мыши, выберите пункт ORACLE Trigger и в появившемся окне нажмите кнопку ORACLE? Entity Trigger. На экране появляется окно Entity Trigger Editor.
Вполе ввода Trigger введите имя триггера и нажмите кнопку New. Затем
спомощью блоков Trigger On, Fire, Scope выберите условия срабатывания триг гера. Если необходимо определить список столбцов таблицы, при изменении которых будет срабатывать триггер, выберите требуемые атрибуты из списка Column(s) и нажмите кнопку Add->. В окне Template Code формируется шаблон триггера, который можно модифицировать. При этом можно использовать спе циальные операторы макроязыка шаблона. С помощью окна Expanded Code можно посмотреть, как этот триггер будет выглядеть после генерации.
3.Можно изменить стандартные шаблоны, обеспечивающие ссылоч ную целостность (см. пункт 1). Для этого выберите какую-либо таблицу, нажмите правую кнопку мыши, выберите пункт ORACLE Trigger и нажмите кнопку ORACLE Trigger Template. На экране появится окно ORACLE Trig ger Template Editor.
246
12.2. Разработка пргтооюений
Выберите в верхнем списке Referential Integrity Type тип триггера, шаблон которого вы желаете изменить. Затем в списке Built-in Trigger Tem plate укажите на подходящий шаблон, в поле Template Name измените его имя, а в окне Template code модифицируйте, при необходимости, код выб ранного шаблона. С помощью кнопки <- Add добавьте имя нового шаблона
вокно User Override, затем с помощью кнопки Attach (второй слева) изме ните стандартный шаблон. При этом напротив стандартного имени триггера
вокне Referential Integrity Type появится новое имя (в списке Attached Trig ger Template).
Чтобы с помощью пакета Erwin разработать хранимую процедуру, выполните следующие шаги.
1.Выберите какую-либо таблицу (процедуры в Erwin связываются с таблицами) на ЛС, щелкните правой клавишей мыши, выберите пункт ORACLE Table Property, а затем — пункт Stored Procedure. На экране появ ляется окно ORACLE Table Property Editor.
2.Нажмите кнопку SP Template. На экране появляется окно Table Stored Procedure Template Editor.
Введите в поле Name имя шаблона процедуры, нажмите кнопку New и
вокне Stored Procedure Template введите код процедуры. Здесь можно ис пользовать операторы макроязыка шаблонов. Нажмите кнопку ОК.
3.В окне ORACLE Table Property Editor в списке Unattached SP Tem plate выберите имя шаблона процедуры и нажмите кнопку <- Attach. При этом имя перемещается в список Attached SP Template. Нажмите кнопку ОК.
После выполнения всех требуемых.описаний можно создать модуль описания разработанной ЛС БД (DDL-описание). Для этого выберите пункт меню Server/Schema Generation. На экране появляется окно ORACLE Shema Generation Report.
Проверьте, чтобы были установлены все требуемые признаки генера ции триггеров, таблиц, индексов и т.д. Чтобы посмотреть модуль описания ЛС БД, нажмите кнопку Preview. Ниже приведена распечатка этого модуля.
CREATE TABLE SEC_CNT (
SEC_CNT_1 |
DECIMAL(9) NOT NULL, |
SEC_CNT_2 |
DATE NULL, |
SEC_CNT_3 |
DATE NULL, |
SEC_CNT_4 |
CHAR( 18) NULL, |
SEC_CNT_5 |
DECIMAL(9) NULL |
); |
|
CREATE UNIQUE INDEX ХРКсчет_по_ЦБ ON SEC_CNT
(
SEC_CNT_1 ASC
);
247
12. Логическое проектирование систем распределенной обработки данных
ALTER TABLE SEC_CNT
ADD ( PRIMARY KEY (SEC_CNT_1));
CREATE TABLE SEC_COU ( |
|
COU_CODE_ORG |
CHAR( 18) NOT NULL, |
COU_CODE_ISSUE |
DECIMAL(9) NOT NULL, |
COU_DATE |
DATE NOT NULL, |
COU_QUOTATION |
FLOAT NULL |
);
CREATE UNIQUE INDEX ХРККурс_продажи ON SEC_COU
(
COU_CODE_ORG |
ASC, |
COU_CODE_ISSUE |
ASC, |
COU_DATE |
ASC |
);
ALTER TABLE SEC_COU
ADD (PRIMARY KEY (COU_CODE_ORG, COU_CODE_ISSUE, COU_DATE));
CREATE TABLE SEC_EMI (
SEC_EMI_1 |
CHAR( 18) NOT NULL, |
SEC_EMI_2 |
DECIMAL(9)NULL, |
SEC_EMI_3 |
DATE NULL, |
SEC_EMI_4 |
LONG NULL, |
SEC_EMI_5 |
DECIMAL(9)NULL |
);
CREATE UNIQUE INDEX ХРКЭмитент ON SEC_EMI
(
SEC_EMI_1 ASC
);
ALTER TABLE SEC_EMI
ADD (PRIMARY KEY (SEC_EMI_1)) ;
CREATE TABLE SEC_GRO (
SEC_PR0_1 CHAR(18) NOT NULL
);
CREATE UNIQUE INDEX ХРКТорговая_га10щадка ON SEC_GRO
(
SEC_PR0_1 ASC
);
248
12.2. Разработка приложений
ALTER TABLE SEC_GRO
ADD (PRIMARY KEY (SEC_PR0_1));
CREATE TABLE SECJSS (
SEC_ISS_1 |
DECIMAL(9) NOT NULL, |
SEC_ISS_2 |
CHAR( 18) NULL, |
SEC_ISS_3 |
DECIMAL(9)NULL, |
SEC_ISS_4 |
DATE NULL, |
SEC_ISS_5 |
CHAR( 18) NULL, |
SEC_ISS_6 |
INTEGER NULL, |
SEC_ISS_7 |
LONG NULL, |
SECJSS_8 |
DECIMAL(18)NULL, |
SEC_ISS_9 |
DECIMAL(9)NULL, |
SEC_ISS_10 |
DATE NULL |
);
CREATE UNIQUE INDEX ХРКЭмиссия_ЦБ ON SECJSS
(
SEC_ISS_1 ASC
);
ALTER TABLE SECJSS
ADD (PRIMARY KEY (SEC_ISS_1));
CREATE TABLE SEC_OP (
SEC_0P_1 |
DECIMAL(9) NOT NULL, |
SEC_0P_2 |
DECIMAL(9) NULL, |
SEC_0P_3 |
CHAR( 18) NULL, |
SEC_0P_4 |
CHAR( 18) NULL, |
SEC_0P_5 |
DECIMAL(9)NULL, |
SEC_0P_6 |
DECIMAL(9)NULL, |
SEC_0P_7 |
DECIMAL( 15) NULL, |
SEC_OP_8 |
DECIMAL( 15) NULL, |
SEC_0P_9 |
DECIMAL( 15) NULL, |
SEC_OP_10 |
DATE NULL |
);
CREATE UNIQUE INDEX ХРКОперация_счета_ЦБ ON SEC_OP
(
SEC_0P_1 ASC
);
ALTER TABLE SEC_OP
ADD ( PRIMARY KEY (SEC_0P_1));
249