Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ю. А. Григорьев, Г. И. Ревунков - Банки данных

.pdf
Скачиваний:
334
Добавлен:
10.02.2015
Размер:
7.54 Mб
Скачать

12. Логическое проектирование систем распределенной обработки данных

 

Сегмент отката

 

 

 

(одна транзакция для

 

 

 

каждого процесса)

Запись «после

Программа 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