私は、データを生成してサーバーに送信するモバイルデバイス(アプリケーションが埋め込まれている)からのビジネスデータを同期するシステムを設計しています。同期された各行は、データベースに特定のビジネスログを生成します。
同期するデータによって、ビジネスデータの最終変更日よりも古い日付(同期データ内)のデータが生成された場合、それを無視して、データベースにログを追加するだけです。アップロードされたデータが処理されると、データベースからデータがフェッチされ、デバイスにダウンロードされます。
書き込み直後のこのダウンロードのため、同期は同期でなければなりません。このような何かが私の既存のソリューションを置き換えるのに十分な価値がある場合は、まだリーダー/ライターパターンを使用することが可能です。より重要なことは、最新のデータをダウンロードできることです。そのデータは全体としてフェッチされ、現時点では差分は実装されていません(後で来る可能性がありますが、問題はありません)。
同じビジネスオブジェクトで複数の同期を実行している可能性があります。それは起こりそうにありませんが、起こり得、それを処理できることを望んでいます。組み込みモバイルアプリケーションを数日間再同期せずに使用しない限り、同期は数秒続くことが予想されますが、数分は続きません。
同期されるデータの量は、同期プロセスも大きくなることは想定されていません。
だから私は私の同期方法で相互排除を使用することになり、より正確には、Javaを使用しており、読み取りをブロックしないように、同期プロセス全体ではなく書き込みメソッドに同期を入れました-同期のみ。
私が知りたいのですが :
日付(信頼できない可能性がある)や同期要求に依存せずにクライアントデータをサーバーデータと同期させるために、しばらくの間(ある程度の成功を収めて)調査してきた1つのアプローチは、 JSONパッチの組み合わせです。 (おそらく [〜#〜] pojo [〜#〜] sの場合)と イベントソース 。
基本的な考え方は、クライアントとサーバーに現在の状態を保存する代わりに、クライアントとサーバーが変更のリストを保存し、イベントまたはパッチリクエストのいずれかを介して相互にメッセージを送ることです。
したがって、クライアントにすべてのデータと日付をサーバーに送信させる代わりに、クライアントはイベントと、クライアントがデータが更新されたと最後に思った時刻に対応するリビジョン番号を送信します。このようなもの:
Server.send("MODIFY FOO", 3);
サーバーはこのイベントを(非同期的に)取得すると、すでに受信している可能性のある他のイベントと調整します。たとえば、同じデータを処理する別のクライアントがすでに一部を変更していて、サーバーのリビジョン番号が5になっている可能性があります。したがって、最後の2つが適用される前に、このリビジョンを適用する必要があります。クライアントは、この変更について通知を受ける必要があります。
サーバーが終了すると、関係するすべてのクライアントに変更が加えられたことと、新しい現在のリビジョン番号が通知されます。次に、クライアントはこれらの変更を適用し、その内部リビジョン番号を更新します。
あなたの走行距離は異なる場合がありますが、私はそれが役立つことを願っています。
編集:このアプローチの別の名前またはそのバリエーションは、この 関連する質問 で述べたように、 メッセージキューイング と呼ばれます。
最初の問題は、データを同期する方法として日付を使用することです。私はあなたの解決策のすべての詳細を得られなかったと確信していますが、私はそれを言うでしょう:
日付は携帯電話で生成されますか?この場合、モバイルで実行されているアプリは常に正しい日付を使用しますか?モバイルデバイスのシステム日付を多少変更できる悪意のあるユーザーはどうですか?異なるタイムゾーンのユーザーはどうですか? @jeffreyが言ったように、デバイスで生成された日付に依存するのは最善のアプローチではないかもしれません。
私が正しく理解していれば、 Optimistic Concurrency Control を使用します。あなたのアプローチに本質的に間違っているものはありません。
この質問は、Springでのオプティミスティックロックの実装に関するものです 。多分あなたはそれにいくつかのインスピレーションを見つけることができます。