对于需要很长时间才能打开的数据集(它是一个存储过程),我想在Datasnap服务器上实现某种缓存。
因此,如果第一次加载此数据集并将其传输到客户端(TClientDataSet),则不应关闭并重新打开以下请求,除非服务器重新启动或调用服务器上的“重新加载”过程。
因此,在第一次打开后,每个新客户端只会收到数据集的副本(克隆),而不刷新/重新加载服务器端数据集。
对于此数据集“缓存”的简单实现,不得为每个会话创建Datasnap服务器数据模块(因为对于每个新会话,服务器端数据集将关闭,直到客户端发送请求以打开DatasetProvider)。也许我可以找到一个克隆数据集的解决方案也用于会话数据模块,但我的基本问题是:
有没有办法覆盖DatasetProvider中的方法,以便客户端仍可以打开,但不能关闭服务器端数据集?
答案 0 :(得分: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;
我再也无法访问代码,确定我无法记住每一个细节,很高兴当前的服务器非常好而且速度快,现在不需要考虑...希望解释机制的工作方式。如果您需要澄清或进一步的帮助,请提交。