最初に決定する必要があるのは、変更が競合する場合にどちらの側が「信頼できる」と見なされるかについての一般的なポリシーです。
つまり、レコード#125が1月5日の午後10時にサーバーで変更され、同じレコードが1月5日の午後11時にいずれかの電話(クライアントAと呼びます)で変更されたとします。最後の同期は1月3日でした。次に、ユーザーは、たとえば1月8日に再接続します。
クライアントとサーバーの両方が最後の同期の日付を知っているという意味で、何を変更する必要があるかを特定するのは「簡単」です。したがって、最後の同期以降に作成または更新されたもの(詳細については以下を参照)を調整する必要があります。
したがって、変更されたレコードは#125だけであるとします。2つのうちの一方が自動的に「勝ち」、もう一方を上書きすることを決定するか、ユーザーがどちらのバージョン(サーバーまたはクライアント)が正しいかを判断して他方を上書きできる調整フェーズをサポートする必要があります。
この決定は非常に重要であり、クライアントの「役割」に重みを付ける必要があります。特に、クライアントとサーバーの間に潜在的な競合がある場合だけでなく、異なるクライアントが同じレコードを変更する可能性がある場合。
[#125が2番目のクライアント(クライアントB)によって変更される可能性があると仮定すると、まだ同期されていないクライアントBが同じレコードのさらに別のバージョンを提供し、以前の競合解決が無効になる可能性があります]
上記の「作成または更新された」ポイントに関して...レコードがクライアントの1つで作成された場合、どのようにしてレコードを適切に識別できますか(これが問題のドメインで理にかなっていると仮定します)?アプリがビジネスの連絡先のリストを管理しているとしましょう。クライアントAが新しく作成されたJohnSmithを追加する必要があると言い、サーバーに昨日クライアントDによって作成されたJohn Smithがある場合...別の人物ではないことを確認できないため、2つのレコードを作成しますか?この競合も調整するようにユーザーに依頼しますか?
クライアントはデータのサブセットの「所有権」を持っていますか?つまり、クライアントBがエリア#5のデータの「権限」になるように設定されている場合、クライアントAはエリア#5のレコードを変更/作成できますか?(これにより、競合の解決が容易になりますが、状況によっては実行不可能になる場合があります)。
要約すると、主な問題は次のとおりです。
- デタッチされたクライアントが新しいレコードを作成する前にサーバーにアクセスしていない可能性があることを考慮して、「ID」を定義する方法。
- 以前の状況では、ソリューションがどれほど洗練されていても、データの重複が発生する可能性があるため、これらを定期的に解決する方法と、「レコード#675」と見なされたものが実際にマージ/置き換えられたことをクライアントに通知する方法を予測する必要があります。レコード#543
- 競合がフラットによって解決されるか(たとえば、「最後の同期以降に前者が更新されている場合、サーバーバージョンは常にクライアントよりも優先される」)、または手動介入によって解決されるかどうかを決定します
- フィアットの場合、特にクライアントが優先されると判断した場合は、さらに変更が加えられる可能性のある、まだ同期されていない他のクライアントの処理方法にも注意する必要があります。
- 前の項目では、データの粒度が考慮されていません(説明を簡単にするため)。私の例のように「記録」レベルで推論する代わりに、フィールドレベルで変更を記録する方が適切な場合があると言えば十分です。または、一度に一連のレコード(たとえば、個人レコード+住所レコード+連絡先レコード)を処理して、それらの集計を一種の「メタレコード」として扱います。
参考文献:
(最後の3つはACMデジタルライブラリからのものであり、あなたがメンバーであるかどうか、または他のチャネルを通じてそれらを取得できるかどうかはわかりません)。
Dr.Dobbsサイトから:
- 2004年5月19日、BillWagnerによるSQLServerCEおよびSQLRDAを使用したアプリの作成(デスクトップPCとモバイルPCの両方のアプリケーションを設計するためのベストプラクティス-Windows / .NET)
arxiv.orgから:
- 競合のない複製されたJSONデータ型-このペーパーでは、JSON CRDTの実装について説明します(競合のない複製されたデータ型-CRDT-は、同時変更をサポートし、そのような同時更新の収束を保証するデータ構造のファミリーです)。