読み取り/書き込み(1対多)
このデータの同期パターンは、以下に示すように、エンティティが1対多の関係に従い、アプリがオフラインの間に複数のエンドユーザーが同じデータを変更する可能性が低いモバイルアプリに推奨されます。
- サーバーデータベースは、時間的とともに変化する可能性のあるマスターデータを保持しています。
- ローカルストレージデータベースは、マスターデータのサブセットを保持し、変更することができます。
- 同期によって、変更されたデータがローカルストレージからサーバーデータベースへ、またその逆方向に送信されます。
- サーバーでは、マスターと詳細エンティティのレコード間の関係を保証しながら、「最後の書き込み優先」の原則に沿ってデータが更新される。この原則では、最新のデータ更新によってそれより前の更新が上書きされます。
以下は、読み取り/書き込み(1対多)パターンの概要です。
-
アプリが変更したローカルストレージデータをサーバーに送り返します。
-
マスターと詳細エンティティのレコード間の関係を維持するために必要な手順を踏みながら、データベースのデータを、ローカルストレージから送信されたデータで更新します。たとえば、ローカルレコードのIDとサーバー上の対応レコードのIDを追跡するために辞書を使用することができます。
-
更新されたデータベースデータを送信します。
-
ローカルストレージのデータを削除し、サーバーから取得したデータで作成し直します。
マッピングについて
このサンプルパターンでは、親エンティティと子エンティティのレコード間の関係を維持するために辞書を使用します。新しい親エンティティレコードをサーバーと同期する場合、辞書は、以下に示すように、ローカルストレージ上の元のIDとサーバーデータベース上の新しいIDの間の対応を追跡します。これが必要な理由は、サーバーデータベースでは親レコードと子レコードが同時に作成されないためです。そのため、辞書マッピングを使用して、同期されていない子レコードを、主サーバーデータベース上で生成される外部キーで更新します。
キー: ローカルレコードID | 値: サーバーレコードID |
---|---|
5 | 135 |
6 | 136 |
7 | 150 |
読み取り/書き込み(1対多)パターンのサンプルモジュールをダウンロードして、ご利用の環境でそのロジックを調べることができます。
データモデル
このサンプルでは、関連するCompany
およびContact
データベースエンティティと、これらに対応するLocalCompany
およびLocalContact
ローカルストレージエンティティを定義します。さらに、LocalCompany
およびLocalContact
エンティティには、レコードの同期状態を追跡するための3つのメタデータアトリビュートを定義します。
アプリケーションのロジックは、以下に示すように、ローカルエンティティのIsFromServer
、IsModified
およびIsActive
メタデータアトリビュートを更新する必要があります。
IsFromServer
: Trueの場合、レコードがサーバーに存在しています。IsModified
: Trueの場合、レコードがローカルで変更されています。IsActive
: Falseの場合、レコードはローカルで削除されていますが、サーバーからは削除されていない可能性があります。
OfflineDataSyncロジック
以下は、OfflineDataSync
クライアントアクションのロジックの説明です。
- ローカルで追加・更新・削除されたCompanyレコードのリストを取得します。
- ローカルで追加・更新・削除されたContactレコードのリストを取得します。
- ローカルで追加・更新・削除されたCompanyおよびContactレコードのリストを入力として、
ServerDataSync
サーバーアクションを呼び出します。サーバーは、データベースのデータを更新し、更新されたCompanyおよびContactレコードのリストを返します。 - ローカルストレージのCompanyレコードをすべて削除し、サーバーから返されたレコードのリストを使用し、ローカルストレージのCompanyレコードを作成し直します。
- ローカルストレージのContactレコードをすべて削除し、サーバーから返されたレコードのリストを使用し、ローカルストレージのContactレコードを作成し直します。
ServerDataSyncロジック
以下は、ServerDataSync
サーバーアクションのロジックの説明です。
-
ローカルで追加・更新・削除されたCompanyレコードのリストを入力として、
SyncCompanies
サーバーアクションを呼び出します。このアクションは、データベースのデータを更新し、新しいCompanyレコードのローカルとデータベースのIDのマッピングを記述した辞書とともに、更新されたCompanyレコードのリストを返します。 -
ローカルで追加されたContactレコードのリストを繰り返し、辞書にあるマッピングを使用し、
LocalContact.CompanyId
アトリビュートをデータベースに作成された対応するCompanyレコードのIDで更新します。これにより、レコードの1対多の関係がサーバーデータベース上で維持されることが保証されます。 -
ローカルで追加・更新・削除されたContactレコードのリストを入力として、
SyncContacts
サーバーアクションを呼び出します。このアクションは、データベース内のデータを更新し、更新されたContactレコードのリストを返します。 -
更新されたCompanyおよびContactレコードのリストを、アクションの出力パラメータに割り当てます。
SyncCompaniesロジック
以下は、SyncCompanies
サーバーアクションのロジックの説明です。
-
ローカルで追加されたCompanyレコードのリストを繰り返します。サーバー上に、新しいデータベースレコードを作成します。また、ローカルレコードのIDと新しく作成されたデータベースレコードのIDとの間の辞書マッピングを作成します。
-
ローカルで変更されたCompanyレコードのリストを繰り返し、サーバー上のデータベースのレコードを更新します。
-
ローカルで削除された(非アクティブ)Companyレコードのリストを繰り返し、サーバー上のデータベースのレコードを削除します。
-
すべてのCompanyレコードをサーバーデータベースから取得します。
-
CompanyレコードのローカルIDとデータベースIDとの間のマッピングを記述した辞書およびCompanyレコードのリストを、アクションの出力パラメータに割り当てます。さらに、同期メタデータアトリビュートに下記の値を設定します。
IsFromServer = True
IsModified = False
IsActive = True
SyncContactsロジック
以下は、SyncContacts
サーバーアクションのロジックの説明です。
-
ローカルで追加されたContactレコードのリストを繰り返し、データベースに新しいレコードを作成します。
-
ローカルで変更されたContactレコードのリストを繰り返し、データベースのレコードを更新します。
-
ローカルで削除された(非アクティブ)Contactレコードのリストを繰り返し、データベースのレコードを削除します。
-
すべてのContactレコードをデータベースから取得します。
-
Contactレコードのリストをアクションの出力パラメータに割り当て、同時に、同期メタデータアトリビュートに適切な値を設定します。
IsFromServer = True
IsModified = False
IsActive = True