Как я могу «заморозить» набор данных на сервере Datasnap? - PullRequest
1 голос
/ 16 августа 2010

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

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

Поэтому после первого открытия каждыйновый клиент получит только копию (клон) набора данных без обновления / перезагрузки набора данных на стороне сервера.

Для простой реализации этого «кэша» набора данных серверный модуль данных Datasnap не должен создаваться для сеанса (посколькудля каждого нового сеанса набор данных на стороне сервера будет закрыт до тех пор, пока клиент не отправит запрос на открытие DatasetProvider).Может быть, я могу найти решение для клонирования набора данных также для модулей данных сеанса, но мой основной вопрос:

Есть ли способ переопределить методы в DatasetProvider, чтобы клиент все еще мог открыться, но не закрытьнабор данных на стороне сервера?

1 Ответ

0 голосов
/ 26 октября 2010

Несколько лет назад некоторые серверы DataSnap, на которых я работал, должны были получать данные с очень-очень медленного сервера SQL Server 7. Затем я разработал «игрушку» кеша сервера на основе TClientDataSets, где «кэшированные провайдеры» подключены к тем «серверам ClientDataSets», которые в свою очередь считывают данные из файлового кеша или из базы данных.

Кэш обновлялся на основе набора жестко заданных правил для каждого набора данных. Когда необходимо обновить кэш, server-ClientDataSet использует провайдера для извлечения данных из базы данных через ADOQuery, а затем данные сохраняются на диске сервера приложений с использованием двоичного формата TClientDataSet. (это позволяет совместно использовать кеш между экземплярами сервера).

Чтобы предотвратить одновременное извлечение информации из базы данных различными экземплярами, когда определяется время обновления кэша, был разработан очень простой метод синхронизации. «Контрольный файл» создается на диске во время операции извлечения данных и удаляется при завершении или сбое. Перед запуском операции извлечения данных экземпляр сервера проверяет существование файла. Если он существует, введите цикл ожидания, пока файл не появится, и проверьте правильность данных в ассоциированном файле .cds ... и действуйте в соответствии с этим. Если файл не существует, пытается создать его, покрывая тот же миллисекундный случай.

Это было , а не приложение 24x7, просто 12x6: D. Метод оказался очень хорошим, я не могу вспомнить ни одного сбоя при такой грубой синхронизации в течение почти 3-х лет, когда я поддерживал этот код ... но вы, возможно, захотите создать более надежный механизм.

Когда нет необходимости обновлять кеш, данные просто загружаются с диска.

Вся работа с кешем выполнялась с использованием методов провайдера.

Итак, отношение было примерно таким:

//
//     Client                    Server
//---------------    -----------------------------------------------------------------
//                                               Cache refresh?
//
//                                                   Yes
//                                                  ----- Provider --- ADOQuery - DB
// ClientDataSet ---- Provider --- ClientDataSet --|
//                                                  ----- LoadFromFile
//                                                   No
//
//

Псевдокод для проверки необходимости обновления и OpenDataSet был таким:

function CacheRequiresRefresh: Boolean
begin
  if not IsPresentLocalData then
    Result := True
  else if ControlRecordIsMoreRecent then
    Result := True
  else if SomeOtherCondition then
    Result := True
  else
    Result := False;
end;

function OpenDataSet;
begin
  repeat
    if CacheRequiresRefresh then
    begin
      if not ControlFilePresent then
        if CreateControlFile then
        begin
          ConnectCDSToProvider;
          CDS.Open;
        end
      else
        if ControlFilePresent then
          WaitUntilControlFileIsNotPresent
    end
    else
      CDS.LoadFromFile('filename.cds');
  until CDS.Active;
end;

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

...