データ同期の競合の処理

分散データアプリケーションを操作する場合、しばしば、既に完了済みの変更と競合するデータ変更がクライアントで試みられることがあります。データ同期の競合が発生する主な事例を次のシナリオに示します。

競合の種類

内容

古いデータによる更新の場合。

クライアントがデータを受信して以降、既にデータが変更されているために、クライアントが変更を確定するときにサーバーが競合を検出します。

競合していた変更についてクライアントが既に確定を解除したときに、クライアントに変更がプッシュされた場合。

クライアントはデータ変更の最中であり、その変更は、サーバーからクライアントにプッシュされた変更と競合します。

古いデータによる削除の場合。

クライアントがアイテムを削除しようとしたときに、そのオブジェクトの古いものを使用して削除しようとした場合に、サーバーが競合を検出します。

既にローカルに削除されたアイテムについて、クライアントに変更がプッシュされた場合。

データに対する更新が発生した直後の時点で、同じデータを削除する要求についてクライアントが既に確定を解除しており、データメッセージがサーバーからクライアントに既にプッシュされています。

クライアントのプッシュがない状態で、削除されたデータを更新する場合。

サーバーから既に削除されたデータをクライアントが更新しようとしています。

クライアントのプッシュがある状態で、削除されたデータを更新する場合。

既に削除されたデータをクライアントが更新しようとしており、データメッセージがサーバーからクライアントに既にプッシュされています。クライアントは更新を送信しようとしますが、クライアント上で競合が存在します。

次の例は、競合が発生したときにクライアントでアラートボックスを表示し、サーバー側のデータを受け入れる、簡単なイベントハンドラです。

...
public function useDS:void {
...

    ds.addEventListener(DataConflictEvent.CONFLICT, conflictHandler);        
...
}

public function conflictHandler(event:DataConflictEvent):void {
    var conflicts:Conflicts = ds.conflicts;
    var c:Conflict;
    for (var i:int=0; i<conflicts.length; i++) {
        c = Conflict(conflicts.getItemAt(i));
        Alert.show("Reverting to server value", "Conflict");
        c.acceptServer();
    }
}

mx.data.Conflicts と mx.data.Conflict、および mx.data.events.DataConflictEvent クラスの詳細については、『Adobe Flex 2 リファレンスガイド』を参照してください。

宛先で Java アダプタを使用する場合は、データの同期を処理し、以前のデータが現在データソースにあるデータと一致しない場合に DataSyncException をスローする、sync メソッドを、アセンブラクラスに記述します。DataSyncException の結果、DataConflictEvent がクライアントで発生します。sync メソッドの詳細については、fill-method および sync-method によるアプローチの使用を参照してください。

次のコードに示すように、競合が発生した場合にどのデータを使用するのかをユーザーに決定してもらうこともできます。PersonForm は、その dataSource プロパティに割り当てられた Person オブジェクトのすべてのプロパティを表示するカスタムコンポーネントを表しています。

// 競合イベントハンドラ
function resolveConflictsHandler():void {
displayConflictsScreen();
}
...
<!-- 競合画面の MXML コード -->
<PersonForm id="serverValue" editable="false" dataSource="{ds.conflicts.current.serverObject}"/> 

<PersonForm id="clientValue" dataSource="{ds.conflicts.current.clientObject}"/>

<PersonForm id="originalValue" dataSource="{ds.conflicts.current.originalObject}" editable="false"/>

<mx:Button label="Accept Server" click="ds.conflicts.current.acceptServer" />
<mx:Button label="Accept Client" click="ds.conflicts.current.acceptClient" />
...

Flex 2.01