読み取り/書き込み(最後の書き込み優先)
このデータの同期パターンは、アプリがオフラインの間に複数のエンドユーザーが同じデータを変更する可能性が低いモバイルアプリに推奨されます。
- サーバーデータベースは、時間的とともに変化する可能性のあるマスターデータを保持しています。
- ローカルストレージデータベースは、マスターデータのサブセットを保持し、変更することができます。
- 同期によって、変更されたデータがローカルストレージからサーバーデータベースへ、またその逆方向に送信されます。
- サーバーでは、「最後の書き込み優先」の原則に沿ってデータが更新されます。この原則では、最新のデータ更新によってそれより前の更新が上書きされます。
以下は、読み取り/書き込み(最後の書き込み優先)パターンの概要です。
-
アプリが変更したローカルストレージデータをサーバーに送り返します。
-
データベースのデータを、ローカルストレージから送信されたデータで更新します。
-
更新されたデータベースデータを送信します。
-
ローカルストレージのデータを削除し、サーバーから取得したデータで作成し直します。
読み取り/書き込み(最後の書き込み優先)パターンのサンプルモジュールをダウンロードします。このサンプルモジュールでは、データの同期の例として複数の企業が使用されています。以下のセクションでは、この同期パターンを自動的に作成する方法を説明し、サンプルモジュールで使用されているデータモデルとロジックについて詳細に説明しています。
エンティティのパターンを自動的に生成する
あるエンティティについて、このパターンを実装するために必要なロジックを自動的に生成するには、以下の手順を実行します。
- Service Studioで[Data]タブを開きます。
- [Local Storage]で、サーバーで同期するエンティティのローカルエンティティを選択します。
- ローカルエンティティを右クリックし、[Create Action to Sync Data (Read/Write)]オプションを選択します。
このオプションは、ローカルエンティティがデータベースエンティティに(Idをデータベースエンティティへの外部キーとして)リンクされている場合にのみ使用できます。これができるのは、[Local Storage]を右クリックしてから[Add Entity from Database...]を選択してローカルエンティティを作成した場合です。
これにより、読み取り/書き込み同期パターンを実装するために必要なアクションが作成されます。
- SyncLocal<Entity>
- ローカルエンティティとサーバーデータベースのエンティティとの間の同期を開始するクライアントアクションです。これは、追加・変更・削除されたローカルレコードをSync<Entity>サーバーアクションに送信し、このアクションが、サーバー側のエンティティの同期を処理します。
- Sync<Entity>
- SyncLocal<Entity>アクションによって呼び出されるサーバーアクションです。受信したローカルエンティティのレコードとサーバーデータベースのレコードを同期します。クライアントのローカルストレージで更新されるデータベースのエンティティの現在のレコードを返します。
変更を追跡し同期プロセスで必要なメタ情報を保存するために、上記のアクションとともに、IsFromServer、IsModifiedおよびIsActiveの新しいアトリビュートがローカルエンティティに追加されます。これらの新しいアトリビュートを最新の状態に保ち同期プロセスに対して一貫性を保つため、アクセラレータは、ローカルエンティティのデフォルトのローカルエンティティアクションの使用を置き換える新しいクライアントアクションを作成します。
- CreateOrUpdateLocal<Entity>ForSync
- CreateOrUpdateLocal<Entity>クライアントアクションを置き換えます。
- DeleteLocal<Entity>ForSync
- DeleteLocal<Entity>クライアントアクションを置き換えます。
- UpdateLocal<Entity>ForSync
- UpdateLocal<Entity>クライアントアクションを置き換えます。
これらのクライアントアクションは、[Logic]タブの[Client Actions](SyncActions_Local<entity>)に作成されます。
このアクセラレータを使用する際の同期プロセスの成功を保証するには、ローカルエンティティのすべてのエンティティアクションを、アクセラレータによって作成された対応する新しいアクションで置き換える必要があります。
このパターンを同期テンプレートの仕組みで実行する場合は、OfflineDataSyncクライアントアクションでSyncLocal<entity>クライアントアクションの呼び出しを追加します。
データモデル
このサンプルでは、Company
データベースエンティティとそれに対応するLocalCompany
ローカルストレージエンティティを定義します。さらに、LocalCompany
エンティティには、レコードの同期状態を追跡するための3つのメタデータアトリビュートを定義します。
アプリケーションのロジックは、以下に示すように、ローカルエンティティのIsFromServer
、IsModified
およびIsActive
メタデータアトリビュートを更新する必要があります。
IsFromServer
: Trueの場合、レコードがサーバーに存在しています。IsModified
: Trueの場合、レコードがローカルで変更されています。IsActive
: Falseの場合、レコードはローカルで削除されていますが、サーバーからは削除されていない可能性があります。
OfflineDataSyncロジック
以下は、OfflineDataSync
クライアントアクションのロジックの説明です。
-
ローカルで追加されたCompanyレコードのリストを取得します。Aggregateでは、以下のフィルタを使用します。
LocalCompany.IsFromServer = False and LocalCompany.IsActive = True
-
ローカルで更新されたCompanyレコードのリストを取得します。Aggregateでは、以下のフィルタを使用します。
LocalCompany.IsModified = True and LocalCompany.IsFromServer = True and LocalCompany.IsActive = True
-
ローカルで削除された(非アクティブ)Companyレコードのリストを取得します。Aggregateでは、以下のフィルタを使用します。
LocalCompany.IsActive = False and LocalCompany.IsFromServer = True
-
ローカルで追加・更新・削除されたCompanyレコードのリストを入力として、
ServerDataSync
サーバーアクションを呼び出します。サーバーは、データベースのデータを更新し、更新されたCompanyレコードのリストを返します。 -
ローカルストレージのすべてのCompanyレコードを削除します。
-
サーバーから返されたレコードのリストを使用し、ローカルストレージのCompanyレコードを作成し直します。
ServerDataSyncロジック
以下は、ServerDataSync
サーバーアクションのロジックの説明です。
-
ローカルで追加されたCompanyレコードのリストを繰り返し、データベースに新しいレコードを作成します。衝突を避けるため、
Company.Id
をNullIdentifier()
に設定してレコードが新しい識別子で作成されるようにします。 -
ローカルで変更されたCompanyレコードのリストを繰り返し、データベースのレコードを更新します。
-
ローカルで削除された(非アクティブ)Companyレコードのリストを繰り返し、データベースのレコードを削除します。
-
すべてのCompanyレコードをデータベースから取得します。
-
Companyレコードのリストをアクションの出力パラメータに割り当て、同時に、同期メタデータアトリビュートに適切な値を設定します。
IsFromServer = True
IsModified = False
IsActive = True