Оптимизация приложений С++Builder в архитектуре клиент/сервер
Страница 3. Минимизация обращений к серверу и сети


 

Минимизация обращений к серверу и сети

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

Использование компонента TDatabase

При использовании нескольких компонентов TDataSet следует иметь в виду, что каждый из них стремится во время выполнения создать неявно свой объект TDatabase для связи с сервером. Если же поместить компонент TDatabase на форму или в модуль данных на этапе проектирования приложения, и связать с ним все компоненты TDataSet, указав его имя в качестве значения свойства DatabaseName этих компонентов, все они будут использовать одну общую связь, обеспеченную этим компонентом.

Использование параметра SQLPASSTHRU MODE

Еще один способ минимизации связей с сервером заключается в изменении значения параметра SQLPASSTHRU MODE компонента TDatabase (либо псевдонима, созданного утилитой конфигурации BDE). Этот параметр определяет, могут ли использоваться общие соединения с базой данных запросами, сгенерированными приложением (например, с помощью компонента TQuery), и запросами, сгенерированными самой библиотекой BDE (например, при реализации навигационных методов компонента TTable). Значением этого параметра по умолчанию является NOT SHARED, позволяющее избежать возможных конфликтов при многопользовательском обновлении данных, но создающее отдельные соединения с базой данных для обоих типов запросов.

Наиболее эффективным с точки зрения минимизации соединений с базой данных значением этого параметра в большинстве случаев является значение SHARED AUTOCOMMIT. При использовании этого значения изменения каждой записи в таблицах немедленно фиксируются сервером независимо от типа вызвавшего их запроса, но при этом оба типа запросов могут использовать одно и то же соединение с базой данных. Этот режим наиболее близок к режиму, в котором используются сетевые версии настольных СУБД. Однако так как сервер в этом случае должен немедленно фиксировать результаты изменения записей, он инициирует и завершает отдельную транзакцию при изменении каждой записи, что может привести к перегрузке сервера и сети и к снижению производительности вместо ожидаемого ее повышения. Поэтому эффективность использования такого режима должна быть обязательно проверена путем тестирования.

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

 

Кэширование метаданных на рабочей станции

Еще один способ минимизации связей с сервером заключается в использовании кэширования структуры таблиц на рабочей станции. В этом случае снижается число обращений к серверу с целью определения метаданных, т.е. количества столбцов в используемых в приложении таблицах, их имен и типов данных. Для этой цели используются следующие параметры псевдонима базы данных (или компонента TDatabase):
ENABLE SCHEMA CACHE - разрешено ли кэширование метаданных;
SCHEMA CACHE SIZE - количество таблиц, структура которых кэшируется;
SCHEMA CACHE TIME - время хранения информации в кэше в секундах; значение -1 соответствует времени хранения данных в кэше до закрытия приложения;
SCHEMA CACHE DIR - каталог для кэширования метаданных.

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

Использование потомков TField в клиентском приложении

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

Кэширование данных на рабочей станции

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

Использование локальных фильтров при небольших объемах данных

Если компонент TDataSet доставляет на рабочую станцию небольшой по объему набор данных, сравнимый с размером кэша рабочей станции (определяемого параметрами MINBUFSIZE и MAXBUFSIZE системных настроек BDE), он будет полностью кэшироваться на рабочей станции. В этом случае применение локальных фильтров более предпочтительно, чем использование запросов с предложением WHERE, направляемых на сервер, так как в первом случае не требуется обращение к серверу.

 
Следующая статья »