次の方法で共有


オフライン データ同期

手記

この製品は提供終了です。 .NET 8 以降を使用するプロジェクトの代わりに、Community Toolkit Datasync ライブラリを参照してください。

オフライン データ同期は、Azure Mobile Apps の SDK 機能です。 データはローカル ストアに格納されます。 アプリがオフラインの場合でも、データの作成、変更、検索を行うことができます。 デバイスがオンラインの場合、データは Azure Mobile Apps サービスと同期されます。 SDK では、クライアントとサービスの両方で同じレコードが変更された場合の競合解決がサポートされます。

オフライン同期には、いくつかの利点があります。

  • アプリの応答性を向上させる
  • ネットワーク接続が悪い場合のアプリの信頼性が向上します
  • 待機時間の長いネットワークまたは従量制課金ネットワークでのネットワーク使用を制限する
  • 切断された使用をサポート

次のチュートリアルでは、Azure Mobile Apps を使用してモバイル クライアントにオフライン同期を追加する方法について説明します。

同期テーブルとは

Azure Mobile Apps SDK は、サービスに直接アクセスする IRemoteTable<T>を提供します。 デバイスにネットワーク接続がない場合、操作は失敗します。 同期テーブル (IOfflineTable<T>によって提供されます) は、ローカル ストアに対して同じ操作を提供します。 その後、ローカル ストアを後でサービスと同期できます。 操作を実行する前に、ローカル ストアを初期化する必要があります。

ローカル ストアとは

ローカル ストアは、クライアント デバイス上のデータ永続化レイヤーです。 ほとんどのプラットフォームではローカル ストアに SQLite が使用されますが、iOS ではコア データが使用されます。 独自のローカル ストアを実装することもできます。 たとえば、SQLCipher で SQLite のバージョンを使用して、暗号化されたストアを生成します。

オフライン同期のしくみ

クライアント コードは、ローカルの変更をデータ同期サービスと同期するタイミングを制御します。 ローカルの変更をプッシュ するまで、サービス 何も送信されません。 同様に、ローカル ストアには、データをプル 場合にのみ、新しいデータまたは更新されたデータ 設定されます。

すべてのテーブル、テーブルの一覧、または 1 つのテーブルに対して、保留中の操作をプッシュできます。

// All tables
await client.PushTablesAsync();

// A list of tables
var tablesToPush = new string[] { "table1", "table2" };
await client.PushTablesAsync(tablesToPush);

// A single table
await table.PushItemsAsync();

同期

プッシュ操作は、操作キュー内のすべての保留中の変更をサービスに送信します。 保留中の変更は、HTTP REST 呼び出しを介してサービスに送信され、データベースが変更されます。

プッシュ操作は、プル操作の前に実行されます。 プル操作では、変更されたデータがサービスからプルされ、ローカル ストアに格納されます。

暗黙的なプッシュ

保留中のローカル更新があるテーブルに対してプルを実行すると、プルはまずそのテーブルのプッシュを実行します。 このプッシュは、既にキューに登録されている変更とサーバーからの新しいデータの間の競合を最小限に抑えるのに役立ちます。 必要に応じて、PullOptionsPushOtherTables を設定して、すべてのテーブルのプッシュを構成できます。

var pullOptions = new PullOptions { PushOtherTables = true };
await table.PullItemsAsync(pullOptions);

レコードのサブセットのプル

必要に応じて、オフライン データベースに含めるレコードを決定するために使用するクエリを指定できます。 例えば:

var query = table.CreateQuery().Where(x => x.Color == "Blue");
await table.PullItemsAsync(query);

増分同期

Azure Mobile Apps では、増分同期が実装されます。最後のプル操作以降に変更されたレコードのみがプルされます。 増分同期を使用すると、大きなテーブルを処理するときに時間と帯域幅を節約できます。

一意のクエリごとに、最後に正常に転送されたレコードの UpdatedAt フィールドは、トークンとしてオフライン ストアに格納されます。 最後の UpdatedAt 値は、デルタ トークン ストアに格納されます。 デルタ トークン ストアは、オフライン ストアのテーブルとして実装されます。

パフォーマンスと一貫性

同期が途中で停止することがあります。 例えば:

  • 同期に使用しているネットワークは、同期プロセス中に使用できなくなります。
  • 同期中にアプリケーションを強制的に閉じます。

オフライン データベース内での整合性の問題のリスクを最小限に抑えるために、各レコードは受信時にデータベースに書き込まれます。 必要に応じて、レコードをデータベースにバッチで書き込むことができます。 バッチ処理操作により、プル操作中のオフライン データベース書き込みのパフォーマンスが向上します。 ただし、テーブル メタデータとテーブル内のデータの間に不整合が生じるリスクも高くなります。

書き込みの間隔は次のように調整できます。

var pullOptions = new PullOptions { WriteDeltaTokenInterval = 25 };
await table.PullItemsAsync(pullOptions);

このコードは、25 個のレコードのバッチに書き込みを収集します。 パフォーマンス テストでは、パフォーマンスが最大 25 の値まで向上することが示唆されています。 WriteDeltaTokenInterval 値が 25 を超える場合、パフォーマンスは大幅に向上しません。

パージ

IOfflineTable<T>.PurgeItemsAsyncを使用して、ローカル ストアの内容をクリアできます。 クライアント データベースに古いデータがある場合、または保留中のすべての変更を破棄する場合は、消去が必要になることがあります。 消去により、ローカル ストアからテーブルがクリアされます。 テーブルを消去するには:

await table.PurgeItemsAsync("", new PurgeOptions());

テーブルに保留中の変更がある場合、PurgeItemsAsync() メソッドは InvalidOperationException エラーをスローします。 この場合は、強制的に消去を実行できます。

await table.PurgeItemsAsync("", new PurgeOptions { DiscardPendingOperations = true });

消去は、キャッシュからすべてのレコードをワイプし、再ダウンロードする必要があるため、オフライン ストア内のテーブルをクリーンアップするための最後の手段です。