1

I'm working on a basic syncing algorithm for a user's notes. I've got most of it figured out, but before I start programming it, I want to run it by here to see if it makes sense. Usually I end up not realizing one huge important thing that someone else easily saw that I couldn't. Here's how it works:

I have a table in my database where I insert objects called SyncOperation. A SyncOperation is a sort of metadata on the nature of what every device needs to perform to be up to date. Say a user has 2 registered devices, firstDevice and secondDevice. firstDevice creates a new note and pushes it to the server. Now, a SyncOperation is created with the note's Id, operation type, and processedDeviceList. I create a SyncOperation with type "NewNote", and I add the originating device ID to that SyncOperation's processedDeviceList. So now secondDevice checks in to the server to see if it needs to make any updates. It makes a query to get all SyncOperations where secondDeviceId is not in the processedDeviceList. It finds out its type is NewNote, so it gets the new note and adds itself to the processedDeviceList. Now this device is in sync.

When I delete a note, I find the already created SyncOperation in the table with type "NewNote". I change the type to Delete, remove all devices from processedDevicesList except for the device that deleted the note. So now when new devices call in to see what they need to update, since their deviceId is not in the processedList, they'll have to process that SyncOperation, which tells their device to delete that respective note.

And that's generally how it'd work. Is my solution too complicated? Can it be simplified? Can anyone think of a situation where this wouldn't work? Will this be inefficient on a large scale?

4

3 に答える 3

2

非常に複雑に聞こえます。中央データベースは、どのデバイスがどのアップデートを受信したかを判断する責任を負うべきではありません。これが私がそれを行う方法です:

  • データベースは、SyncOperations変更ごとにテーブルを保持します。それぞれに昇順SyncOperationの番号が付けられています (つまり、 .)。change_idchange_id INTEGER PRIMARY KEY AUTOINCREMENT
  • 各デバイスは、current_change_id最後に見た変更を表す番号を保持しています。
  • デバイスが更新する必要がある場合、それは行いSELECT * FROM SyncOperations WHERE change_id > current_change_idます。これにより、最新にする必要があるすべての変更のリストが取得されます。それぞれを時系列で適用します。

これには魅力的な機能があり、必要に応じて、新しいクライアントを作成するだけで新しいデバイスを初期化できますcurrent_change_id = 0. 次に、すべての更新を取り込みます。


2 人のユーザーが同時に編集を行うことができる場合、これは実際には機能しないことに注意してください (どちらの編集が「勝つ」のでしょうか?)。編集を自動的にマージするか、ユーザーに通知を出すことができます。何らかのインスピレーションが必要な場合は、gitバージョン管理システム (または Mercurial、または CVS...) の競合する編集について調べてください。

于 2012-04-16T05:37:52.280 に答える
1

同期操作を処理する方法については、SyncML を参照してください (http://www.openmobilealliance.org/tech/affiliates/syncml/syncml_sync_protocol_v11_20020215.pdf)。SyncML はしばらく前から存在しており、公開標準として、かなりの精査とレビューが行われてきました。また、いくつかのコーディングの手がかりを提供できるオープン ソースの実装 (Funambol が思い浮かびます) もあります。仕様全体を使用する必要はありませんが、それを読むと、データの同期について「ああ」と思う瞬間がいくつかあるかもしれません。何をする必要があるかを考えるのに役立つことはわかっています。

マーク

PS プロトコルの新しいバージョン - http://www.openmobilealliance.org/technical/release_program/docs/DS/V1_2_1-20070810-A/OMA-TS-DS_Protocol-V1_2_1-20070810-A.pdf

于 2012-04-17T19:13:28.197 に答える
0

他の場所のデータベースで操作を追跡するという基本的な考え方を見たことがあるので、それを機能させることができるとあえて言います。異なるデバイスがほぼ同時に使用されている場合にどうなるかを考えて、競合する変更を送信することになる場合があります。たとえば、同じメモを編集する2つの異なる試みです。これは、ユーザーインターフェースの変更として表面化する可能性があり、ユーザーが介入してそのような競合を手動で解決できるようにします。

于 2012-04-16T04:39:27.823 に答える