1

对于需要很长时间才能打开的数据集(它是一个存储过程),我想在 Datasnap 服务器上实现某种缓存。

因此,如果此数据集是第一次加载并传输到客户端(TClientDataSet),则不应为以下请求关闭并重新打开它,除非服务器重新启动或调用服务器上的“重新加载”过程。

因此,在第一次打开后,每个新客户端只会收到数据集的副本(克隆),而不会刷新/重新加载服务器端数据集。

对于此数据集“缓存”的简单实现,不得在每个会话中创建 Datasnap 服务器数据模块(因为对于每个新会话,服务器端数据集将关闭,直到客户端发送打开 DatasetProvider 的请求)。也许我可以找到一个解决方案来克隆会话数据模块的数据集,但我的基本问题是:

有没有办法覆盖 DatasetProvider 中的方法,以便客户端仍然可以打开,但不能关闭服务器端数据集?

4

1 回答 1

0

几年前,我工作的一些 DataSnap 服务器不得不从非常慢的 SQL Server 7 服务器中提取数据。然后我设计了一个基于 TClientDataSets 的服务器缓存“玩具”,其中“缓存提供程序”连接到那些“服务器 ClientDataSets”,后者依次从文件缓存或数据库中读取数据。

根据每个数据集的一组特定硬编码规则刷新缓存。当需要刷新缓存时,server-ClientDataSet 使用提供程序通过 ADOQuery 从数据库中提取数据,然后使用 TClientDataSet 的二进制格式将数据保存到 app-server 磁盘。(它启用服务器实例之间的缓存共享)。

为了防止不同的实例在确定是时候更新缓存时同时从数据库中提取信息,开发了非常基本的同步方法。在数据检索操作期间在磁盘上创建一个“控制文件”,并在完成或失败时删除。在拉数据操作开始之前,服务器实例检查文件是否存在。如果存在,则进入等待循环,直到文件不存在并检查 .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;

我无法再访问代码了,当然我不记得每一个细节,幸运的是,当前的服务器非常好并且足够快,现在不需要考虑这个......希望解释机制的工作方式。如果您需要澄清或进一步的帮助,请发表评论。

于 2010-10-26T19:29:44.857 回答