Программирование >>  Проектирование баз данных 

1 ... 144 145 146 [ 147 ] 148 149 150 ... 184


переходит на следующее поле. (В этом примере подразумевается, что значения вводятся непосредственно, а не выбираются из группы селекторных кнопок, что само по себе представляет форму локальной реализации правила в интерфейсе.)

Проектировщик может подумать, что он стоит перед выбором: реализовать эту проверку в интерфейсе как правило для интерфейса или реализовать ее на сервере данных как правило для данных. На самом деле этого выбора не существует - есть, по сути дела, два правила, работающих в разных средах, и оба они должны быть реализованы. Правило для интерфейса должно быть реализовано потому, что пользователи требуют моментальной обратной связи, а правило для данных потому, что в обеспечении целостности данных сервер не должен зависеть от интерфейса.

Когда мы представляем эти соображения группе программистов или проектировщиков, они обычно начинают беспокоиться о снижении производительности и возможности выхода двух этих правил из синхронного режима. Давайте рассмотрим эти проблемы по очереди. Избыточная проверка осуществляется в интерфейсе, и, как правило, во внещней системе (особенно в средах клиент/сервер) нет дефицита ресурсов ЦП. Кроме того, эту проверку выполнять очень легко. Если принять в качестве аргумента положение о том, что эта проверка должна выполняться во внутренней системе независимо от того, выполняется ли она во внещней системе, то можно считать, что ответ на вопрос о причинах снижения производительности найден.

На рис. 16.1 показано, как данное правило реализовано и в базе данных, и в интерфейсе (в данном случае в программе на Visual Basic).

CREATE TABLE emp

( empno ...

, sex CHAR (1) NOT NULL CONSTRAINT (emp ccl)

CHECK (sex IN (M,F))


Private

gBex;Ptease &Jleraher.kor,f%r Sex rerml.SesfrSetFocus ~

End ,

Puc. 16.1. Реализация одного и того же правила в базе данных и в интерфейсе (средствами Visual Basic)



Если эти правила выходят из синхронного режима, то мы фактически получаем преимущество. Рассмотрим случай, когда интерфейс требует, чтобы значение было либо Г, либо т , а база данных - чтобы оно было либо F , либо М . Значение, которое проходит проверку в интерфейсе, в базе данных ее не пройдет, и ввести либо изменить значение поля Sex с помощью этого интерфейса совершенно невозможно. В результате код интерфейса (или, по крайней мере, часть его) будет неработоспособным. Этот факт быстро высветит проблему и приведет к тому, что на нее обратят внимание и устранят. Представьте себе ситуацию, в которую мы попали бы, если бы в 1 базе данных проверка не выполнялась. В этом случае приложение с ошибкой установило бы строчные значения и испортило бы базу данных.

Больщинство проектировщиков и администраторов БД предпочитают, чтобы то или иное средство вообще перестало работать, чем продолжало 1 работать неправильно, но многие пользователи не столь дальновидны. Не уподобляйтесь им!

Вопросы блокировки

Если мы решили реализовать правило в интерфейсе, то должны быть очень осторожны в вопросах блокировки (которые подробно рассматриваются в главе 18). Давайте поговорим о следующем правиле:

Счет клиента не может дебетоваться, если текущий остаток за вычетом суммы данной дебетовой операции превышает кредитный лимит по счету.

Предположим, что для ввода суммы дебетовой операции мы пользуемся экранной формой и что это правило реализовано в интерфейсе. Интерфейс делает следующее:

1. Выбирает сведения о счете, в том числе о кредитном лимите и текущем остатке.

2. Дает возможность пользователю ввести сведения о новой дебетовой операции (получатель платежа, дата, сумма и т.д.).

3. Если верно выражение остаток - сумма дебетовой операции > кредитный лимит, фиксирует транзакцию. В противном случае выдает ошибку и производит откат транзакции.

Проблема при такой реализации заключается в том, что правило может не сработать, если в промежутке времени между шагами 1 и 3 другие зафиксированные транзакции внесли изменение в счет или другой пользователь обновил кредитный лимит. Вероятность этого может быть довольно высокой, поскольку на шаге 2 мы ждем, пока пользователь введет данные в экранную форму.

Можно попробовать разрешить эту ситуацию с помощью предварительной , или пессимистической , блокировки на шаге 1 посредством



предложения SELECT...FOR UPDATE, но эта блокировка должна оставаться в силе, пока мы ожидаем ввода данных пользователем.

Предупреждение

Даже этот метод не поможет, если остаток не хранится в записи об остатке как производное значение (предположительно, ведомое триггерами). Если остаток запрашивается путем выполнения операции подведения итога, то единственный путь, позволяющий гарантировать истинность результата, - установить разделяемую блокировку на каждой таблице, содержимое которой может учитываться при вычислении конечного результата. Если таблицы подвержены интенсивным изменениям, то устанавливать для них разделяемые блокировки на время пользовательского ввода-вывода - это подход, отнюдь не повышающий производительность.

С аналогичной проблемой приходится сталкиваться при вводе уникальных ключей. Интерфейс технически может гарантировать уникальность вводимого ключа только в том случае, если:

реально выполняется требуемая DML-операция;

устанавливается разделяемая блокировка на таблице, над которой в конечном итоге будет выполнена эта DML-операция.

Очень эффективное решение всех этих проблем - выполнить проверку в интерфейсе без блокировки, а затем повторить ее в логике обработки в момент фиксации. (Во многих случаях логика обработки не обязательно должна явно выполнять эту проверку, потому что при вьщаче DML-операций проверка выполняется неявно.)

Такая стратегия, предполагающая наличие двух типов проверок (мы называем их рекомендуемой и обязательной проверками), может быть использована для того, чтобы получить возможность продолжать практически любую транзакцию без блокировки ввода-вывода с терминала. Кроме того, она обеспечивает высокий уровень обратной связи с пользователем. Однако, как известно, ничто в этом мире не достается бесплатно. Помимо трафика сообщений и нагрузки на ЦП, связанной с запросами к базе данных, необходимыми для выполнения рекомендуемых проверок, существует также риск того, что рекомендуемая проверка даст ошибочный результат.

Может случиться и так, что рекомендуемая проверка пройдет, а окончательная фиксация окажется невозможной из-за результатов обязательной проверки (например, потому что другой пользователь фиксирует транзакцию, где используется кредит, который ваша транзакция определила как имеющийся, но не заблокировала). Кроме того, в некоторых случаях проверка может сообщить о нарушении там, где фиксация была бы успещно выполнена. По этой причине мы советуем делать так, чтобы при рекомендуемой проверке способ сообщения об ошибке позволял пользователю продолжать работу (по его усмотрению) после рекомендательного сообщения. В среде, где пользователь может одновременно выполнять несколько транзакций, это также даст ему возможность рещить проблему в

------ ----------. .......ч 447



1 ... 144 145 146 [ 147 ] 148 149 150 ... 184

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика