MIDAS. Практическое применение
| Категория реферата: Рефераты по информатике, программированию
| Теги реферата: курсовая работа по менеджменту, доклад по обж
| Добавил(а) на сайт: Roman.
Предыдущая страница реферата | 4 5 6 7 8 9 10 11 12 13 14 | Следующая страница реферата
Создаваемый нами сервер приложений будет отдельным исполняемым модулем. Этот модуль затем можно будет расположить на отдельном компьютере, который сможет производить расчеты для нескольких клиентов и синхронизировать их работу.
Сервер приложений должен обеспечивать обработку документа как единого объекта, поэтому разумным будет выделить работу с ним в отдельный класс, в данном случае потомок TRemoteDataModule. Нам также понадобится модуль данных для работы со справочником поставщиков и получателей, и выдачи списка документов. Отчет я решил также выделить в отдельный модуль. В итоге на сервере необходимо создать три потомка TRemoteDataModule: rdmCommon (общий модуль со списками поставщиков/получателей и документов), rdmDoc и rdmReport – соответственно для документа и отчета.
Мастер создания удаленного модуля данных предлагает по умолчанию политику загрузки исполняемого модуля Multiple instance и модель потоков Apartment. Это именно то, что нам нужно! Действительно, Instancing = Internal приведет к созданию серверного компонента в клиентском процессе (это распространяется только на сервер, создаваемый в виде DLL). При Single instance каждая клиентская часть будет соединяться со своим собственным экземпляром сервера приложений, а синхронизацию проще сделать, если все клиенты подсоединяются к одному экземпляру сервера приложений. Выбор модели потоков Apartment позволит избежать ручной синхронизации доступа к данным компонента.
Теперь остается создать три (опять три, это тоже случайно) потомка TRemoteDataModule, расположить на них компоненты доступа к данным и написать код для обработки данных.
При этом необходимо учитывать, что при использовании модели потоков Apartment каждый модуль данных работает в своем потоке, и поэтому в каждом модуле должен находится отдельный компонент TIBDatabase.
При прямом доступе провайдера к базе (свойство ResolveToDataset = false) MIDAS также требует наличия отдельной копии объекта TIBTransaction для каждого компонента доступа к данным, то есть у каждого провайдера должна быть своя транзакция. Компонент TIBTransaction специфичен для компонентов прямого доступа к Interbase, обычно работа с транзакциями возложена на компонент соединения с базой данных.
ПРИМЕЧАНИЕ При использовании сервера Interbase для доступа к данным по технологии MIDAS логично использовать IBX, провайдеры данных великолепно работают с этими компонентами. Единственное замечание – Borland сертифицировала на момент написания статьи версию IBX 4.52. Более поздние версии работают в составе MIDAS несколько иначе, чем раньше. В частности, транзакции теперь не закрываются автоматически после выборки данных. |
Рассмотрим удаленные модули данных по порядку, и начнем с модуля справочников (rdmCommon) (рисунок 2).
Рисунок 2. Общий модуль rdmCommon.
Компонент ibqDocs имеет тип TIBDatabase и обеспечивает соединение модуля с сервером БД. У меня БД находится в каталоге d:projectsdocmidasdata и называется doc.gdb. В прилагающемся к статье проекте сервер приложений позволяет указать произвольное местонахождение сервера БД и файла базы данных.
Для того, чтобы при каждом соединении сервер приложений не запрашивал имя пользователя и пароль, они просто указаны в параметрах соединения. Имя пользователя SYSDBA и пароль masterkey являются установками по умолчанию при инсталляции сервера Interbase.
Перечислим компоненты модуля. К компоненту транзакции ibtClient подсоединен запрос ibqClient (компонент TIBQuery), к которому, в свою очередь, присоединен провайдер dspClient. Соответственно, у транзакции и запроса указано соединение с БД ibdDocs. Остается только установить тип транзакции read committed (удобнее всего это сделать, дважды щелкнув на соответствующем компоненте, и выбрав его тип), и в свойстве SQL-запроса записать “select * from client”. Теперь провайдер может предоставлять клиентской части возможность работать со справочником клиентов. Но для повышения комфорта нужно добавить возможность нескольким пользователям изменять одновременно разные поля в одной и той же записи в таблице (их два: Name и Phone). Делается это довольно просто, в редакторе полей (Fields Editor) ibqClient нужно создать постоянный список всех полей запроса, и у поля CLIENT_ID в его свойство ProviderFlags добавить опцию pfInKey. Затем у провайдера dspClient установить свойство UpdateMode в upWhereChanged. В этом случае, если разные клиентские части изменят разные поля одной записи в таблице CLIENT, сервер приложений примет эти изменения. В случае, если будут изменены одни и те же поля одной записи, клиентской части будет выдано сообщение вида «Запись изменена другим пользователем».
ПРИМЕЧАНИЕ Здесь мне хотелось бы остановиться на свойствах TField.ProviderFlags и TDataSetProvider.UpdateMode. Дело в том, что меня часто спрашивают, что зависит от значений этих свойств, а зависит от них довольно много. В справке по VCL эти свойства описаны, на мой взгляд, недостаточно подробно, а связь между ними достаточно тесная. Итак, пусть имеется компонент TQuery, TIBQuery или какой-то другой (запрос), соединенный с сервером БД, и к нему присоединен TDataSetProvider. В этом случае на логику работы оказывают влияние именно значения свойства ProviderFlags полей этого запроса, аналогичные свойства полей на клиентской стороне никакого влияния не оказывают. Комбинация значений этих свойств полностью определяет, как будут производиться операции обновления данных на сервере БД. Рассмотрим обновление данных в таблице. Добавление и удаление записи происходит аналогично. Провайдер с установленным свойством ResolveToDataset = false при обновлении записи формирует SQL-запрос вида UPDATE <Table> SET <Field1>=<NewValue1>, ... WHERE <Field1>=<OldValue1> AND ..., в полном соответствии со стандартом SQL (при ResolveToDataset=True производится поиск и обновление прямо в таблице). Имя таблицы <Table> берется из Dataset (провайдер великолепно понимает запросы SQL вида Select from...), либо задается в обработчике OnGetTableName. Значения NewValue и OldValue для каждого поля берутся из пакета обновления, посылаемого провайдеру. Имена полей в выражениях SET и FROM формируются автоматически, как раз на основе свойств ProviderFlags и UpdateMode того набора данных, через который провайдер работает с базой. Алгоритм следующий: В предложение SET входят только те поля, у которых установлен флаг pfUpdate в свойстве ProviderFlags (требуется обновлять в базе данных) и OldValue <> NewValue (значение поля было изменено). Предложение WHERE формируется следующим образом: Берутся все поля, у который установлены [pfInKey, pfInWhere], фактически это первичный ключ. При UpdateMode=upWhereKeyOnly больше никаких полей не берется. При UpdateMode=upWhereChanged к полям первичного ключа добавляются те поля, у которых OldValue <> NewValue и pfWhere in ProviderFlags, что позволяет делать проверку на изменение тех же полей другим пользователем. При UpdateMode=upWhereAll в список полей WHERE входят все поля записи, у которых pfWhere in ProviderFlags. В случае, если запись в таблице на сервере не найдена (нет записей, удовлетворяющих условию WHERE), пользователю выдается сообщение вида "Запись изменена другим пользователем", вне зависимости от причины. Остается одно значение флага, pfHidden. Поля с этим флагом не передаются клиентскому приложению, и не принимаются от него, флаг указывает, что эти поля - только для использования на стороне сервера. Рекомендуем скачать другие рефераты по теме: зимнее сочинение, шпаргалки по уголовному. Категории:Предыдущая страница реферата | 4 5 6 7 8 9 10 11 12 13 14 | Следующая страница реферата Поделитесь этой записью или добавьте в закладки |