Использование наборов данных в распределённой среде
Использование наборов данных в распределённой среде предполагает передачу набора данных из одной процедуры в другую. Из этой части вы узнаете об одной из самых мощных функций набора данных – его способности транспортироваться или «маршализироваться» между процедурами.
Передача набора данных в качестве параметра позволяет перемещать сложные наборы данных между сервером и клиентом, из процедуры в процедуру или из приложения в приложение. Возможность передачи набора данных в качестве параметра является основой для построения распределённых приложений.
Наиболее распространённой целью передачи набора данных в качестве параметра является сценарий «round-trip», о котором было рассказано на первом уроке:
- Клиент запрашивает набор данных с сервера путём вызова на сервере процедуры, которая заполняет набор данных и возвращает его в качестве параметра клиенту.
- Клиент вносит изменения в полученный набор данных.
- Клиент отправляет изменения на сервера в виде параметра путём вызова процедуры на сервере, которая применяет изменения к базе данных и возвращает результат изменений клиенту.
- Клиент согласовывает изменения в своей копии набора данных.
На этом уроке вы познакомитесь с реализацией первых двух шагов сценария «round-trip». На следующем уроке будет рассказано о том, как обновлять набор данных.
Передача набора данных
Во время разработки приложения вы должны спланировать как набор данных будет использоваться в ABL-сессии и между ABL-сессиями. Код на стороне сервера может иметь несколько процедур, которые используются для обработки клиентских запросов на получение набора данных. Например, клиент может вызвать процедуру GetData, которая формирует запрос, используемый для заполнения набора данных. Затем GetData вызывает функцию PopulateData, которая заполняет набор данных и возвращает его в GetData. И наконец, GetData возвращает набор данных клиенту.
Хорошей практикой считается гарантирование того, чтобы в пределах одной ABL-сессии использовался один и тот же набор данных при выполнении GetData и PopulateData. То есть, набор данных должен передаваться по ссылке в рамках одного и того же процесса. А если набор данных передаётся между клиентом и сервером (между разными ABL-сессиями), то он должен передаваться по значению.
Передача набора данных в пределах ABL-сессии
Предварительно описанный набор данных может быть передан как параметр с типом INPUT, OUTPUT или INPUT-OUTPUT. Синтаксис описания набора данных передаваемого в качестве параметра по имени следующий:
DEFINE { INPUT | OUTPUT | INPUT-OUTPUT } PARAMETER DATASET FOR <dataset-name>.
Пример:
DEFINE OUTPUT PARAMETER DATASET FOR dsOrderOrderLine.
Этот оператор выполнит возврат набора данных dsOrderOrderLine вызывающей процедуре
Когда процедура, выполняемая в одной ABL-сессии, вызывает другую процедуру передавая набора данных в качестве параметра, в вызывающей процедуре параметру указывается ключевое слово BY-REFERENCE.
В следующем примере процедура GetData.p вызывает процедуру PopulateData:
RUN PopulateData (INPUT pCriteria, OUTPUT DATASET dsOrderOrderLine BY-REFERENCE).
В этом случае обе процедуры используют один и тот же объект набора данных во время выполнения, что является наилучшей практикой.
Передача набора данных в другую ABL-сессию
Передача набора данных между разными ABL-сессиями должна выполняться по значению. Вот упрощённый синтаксис для определения параметра набора данных в серверном коде:
DEFINE { OUTPUT | INPUT-OUTPUT } PARAMETER DATASET-HANDLE <dataset-handle-name>.
Для извлечения набора данных с сервера используется ключевое слово OUTPUT.
Ниже приведён пример кода серверной части приложения, в котором набор данных описывается как параметр и возвращается клиенту. Обратите внимание на описания файла внешней библиотеки процедур. В этой библиотеке хранится код всех внутренних процедур, связанных с доступом к набору данных dsOrderLine.
{include\dsOrderOrderLine.i} PROCEDURE GetData: DEFINE INPUT PARAMETER pFilter AS CHARACTER NO-UNDO. DEFINE OUTPUT PARAMETER DATASET-HANDLE phdsOrderOrderLine. /* заполнение набора данных dsOrderOrderLine */ /* присвоить возвращаемому параметру «хэндл» набора данных */ phdsOrderOrderLine = DATASET dsOrderOrderLine:HANDLE. RETURN. END PROCEDURE.
Минимизация накладных расходов при передаче набора данных
Когда временные таблицы, входящие в набор данных, передаются по сети, их схема иногда может существенно влиять на производительность, приводя к ненужным накладным расходам и медленной транспортировке набора данных.
Если клиентский код имеет собственное статическое описание набора данных, то вы должны использовать атрибут SCHEMA-MARSHAL для ограничения объёма информации, передаваемой по сети при возврате набора данных. По умолчанию этот атрибут имеет значение FULL, что означает необходимость в отправке всей информации о схеме. Чтобы ограничить передаваемый объём необходимо установить атрибуту SCHEMA-MARSHAL значение NONE для каждой временной таблицы набора данных. Атрибут нельзя установить на объект набора данных.
Атрибут SCHEMA-MARSHAL устанавливается в коде серверной части приложения, который отправляет набор данных клиенту. Не надо указывать его на стороне клиента.
Синтаксис оператора для указания того, что временная таблица в наборе данных должна быть передана без описания её схемы:
<table-handle>:SCHEMA-MARSHAL = "NONE".
Пример:
ASSIGN TEMP-TABLE ttOrder:SCHEMA-MARSHAL = "NONE" TEMP-TABLE ttOrderLine:SCHEMA-MARSHAL = "NONE".
В этом примере информация о схеме не будет передаваться для временных таблицы ttOrder и ttOrderLine. При этом процедура вызова должна иметь соответствующее статическое описание набора данных и временных таблиц для успешного получения переданного набора данных.