Статьи Королевства Дельфи

         

То есть алгоритм получается примерно


То есть алгоритм получается примерно таким:


  1. Пользователь нажимает кнопку «Создать документ»
  2. Старт транзакции
  3. Вставка записи заголовка и получение нового номера документа
  4. Формирование позиций документа
  5. Пользователь нажимает кнопку «Сохранить документ»
  6. Завершение транзакции.


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

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

Наилучшим решением представляется использование механизма получения очередных номеров, независимого от таблиц и транзакций, аналогичного, например, генераторам Interbase. Кстати, если СУБД, на которой вы работаете, не имеет такого механизма, но поддерживает вызов внешних функций, то генераторы a la Interbase достаточно просто разработать самостоятельно. Тогда алгоритм формирования документа станет таким:


  1. Пользователь нажимает кнопку «Создать документ»
  2. Получение очередного номера документа
  3. Формирование записи заголовка и позиций документа
  4. Пользователь нажимает кнопку «Сохранить документ»
  5. Сохранение документа: Старт транзакции, запись в таблицы заголовков и позиций, завершение транзакции.


Преимущества этой схемы достаточно очевидны: транзакция открывается только в момент реальной записи документа (т.е. тогда, когда пользователь нажал кнопку «Сохранить»), время ее работы определяется исключительно объемом данных документа и не зависит от настроения пользователя.

Если вы используете Delphi или C++ Builder, то для реализации подобной схемы подойдут компоненты TClientDataSet и TUpdateSQLProvider.

Сергей Королев

¹ - Здесь и далее используется диалект SQL для СУБД Interbase

² - Joe Celko -SQL-гуру, автор постоянной колонки журнала (бывш. DBMS magazine),
в которой часто публикуются интересные задачи для знатоков SQL.


Содержание  Назад  Вперед