数年前、私が働いていたいくつかの DataSnap サーバーは、非常に遅い SQL Server 7 サーバーからデータを取得する必要がありました。次に、ファイル キャッシュまたはデータベースからデータを読み取る「サーバー ClientDataSets」に「キャッシュされたプロバイダー」が接続されている TClientDataSets に基づいて、サーバー キャッシュ「おもちゃ」を作成しました。
キャッシュは、データセットごとに特定のハードコードされた一連のルールに基づいて更新されました。キャッシュを更新する必要がある場合、server-ClientDataSet はプロバイダを使用して ADOQuery を介してデータベースからデータを取得し、TClientDataSet のバイナリ形式を使用してデータをアプリケーション サーバー ディスクに保存します。(サーバー インスタンス間のキャッシュ共有を有効にします)。
キャッシュを更新する時期であると判断したときに、異なるインスタンスが同時にデータベースから情報をプルするのを防ぐために、非常に基本的な同期方法が開発されました。「制御ファイル」は、データ検索操作中にディスク上に作成され、完了または失敗時に削除されます。データのプル操作が開始される前に、サーバー インスタンスはファイルの存在を確認します。存在する場合は、ファイルが存在しなくなるまで待機ループに入り、.cds 関連ファイル内の有効なデータを確認し、それに応じて動作します。ファイルが存在しない場合は、まったく同じミリ秒のケースをカバーして作成を試みます。
これは24 時間年中無休のアプリケーションではなく、12 時間 6 日のアプリケーションのようなものでした:D. この方法は非常に優れていることが証明されました。私はそのコードを維持していたほぼ 3 年間、この失礼な同期で 1 回も失敗したことを覚えていません..しかし、より堅牢なメカニズムを作成する必要があるかもしれません。
キャッシュを更新する必要がない場合、データはディスクから読み込まれます。
すべてのキャッシュ作業は、プロバイダー メソッドを使用して行われました。
したがって、関係は次のようになりました。
//
// 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;
私はもうコードにアクセスできません。確かにすべての詳細を思い出すことはできません。幸いなことに、現在のサーバーは非常に優れており、今これについて考える必要がないほど十分に高速です...メカニズムがどのように機能するかを説明したいと思います. 明確化またはさらに支援が必要な場合は、コメントしてください。