Mobile Link クライアントが更新済みのローを Mobile Link サーバに送信するときは、更新された値 (更新後または新しいイメージロー) だけでなく、Mobile Link サーバとの最後の同期で得た古いローの値 (更新前または古いイメージロー) のコピーも含まれています。更新前イメージローが中央データソースの現在の値と一致しないと、競合が検出されます。
SQL ベースのアップロードの場合、Mobile Link 統合データベースが中央データソースであり、Mobile Link は競合の検出と解決用に特別なイベントを提供しています。
競合の解決を参照してください。
ダイレクトアップロードの場合、新しいローと古いローにプログラムを使用してアクセスして、競合の検出と解決に使用できます。
UpdateResultSet (UploadedTableData.getUpdates メソッドが返す) は、競合処理に使用する特別なメソッドが含まれるように、Java または .NET 標準の結果セットを拡張したものです。setNewRowValues は、リモートクライアントからの新しい更新された値を返すように UpdateResultSet を設定します (デフォルトモード)。setOldRowValues は、古いロー値を返すように UpdateResultSet を設定します。
UpdateResultSet のメソッド .setOldRowValues を使用することによって、リモートデータベースのローの変更される前の値を取得します。返された値をデータソースの既存のロー値と比較します。比較したローが同じではない場合、競合が存在しています。
アップロード中に競合を検出したら、カスタムビジネス論理を使用して競合を解決できます。競合は、Java コードまたは .NET コードによって処理されます。
XML ドキュメント内の在庫を追跡していて、XML ドキュメントを中央データソースとして使用すると仮定します。User1 は、リモートデータベースの 1 つである Remote1 を使用します。User2 は、別のデータベースである Remote2 を使用します。
XML ドキュメント、User1、User2 の最初の在庫数はすべて 10 個です。User1 が、3 個を販売し、Remote1 にある在庫数を 7 個に更新します。User2 は 4 個販売し、Remote2 にある在庫数を 6 個に更新します。Remote1 が同期を実行すると、中央データベースは 7 個に更新されます。Remote2 が同期を実行すると、在庫の値が 10 個ではなくなっているため、競合が検出されます。この競合をプログラムで解決するには、次のような 3 つのロー値が必要となります。
中央データソースにある現在の値。
Remote2 がアップロードした新しいローの値。
Remote2 が最後の同期中に取得した古いローの値。
この場合、ビジネス論理は新しい在庫数を計算し、競合を解決するために次の式を使用します。
current data source - (old remote - new remote) -> 7 - (10-6) = 3 |
Java と .NET の次のプロシージャでは、ダイレクトアップロードでのこのような競合を解決する方法を、次のテーブルを例に示しています。
CREATE TABLE remoteOrders ( pk integer primary key not null, inventory integer not null ); |
handle_UploadData 接続イベント用の Java メソッドを登録します。
handle_UploadData 接続イベントを参照してください。
たとえば、次のストアドプロシージャコールは、スクリプトバージョン ver1 を同期するときに、handle_UploadData 接続イベントに対して HandleUpload という Java メソッドを登録します。Mobile Link 統合データベースに対してこのストアドプロシージャを実行します。
call ml_add_java_connection_script( 'ver1', 'handle_UploadData', 'OrderProcessor.HandleUpload' ) |
同期イベント用のメソッド登録の詳細については、次の項を参照してください。
アップロード内のテーブルの UpdateResultSet を取得します。
OrderProcessor.HandleUpload メソッドは、remoteOrders テーブルの UpdateResultSet を取得します。
// method for handle_UploadData event public void HandleUpload( UploadData u_data ) { // Get UploadedTableData for the remoteOrders table. UploadedTableData u_table = u_data.getUploadedTableByName("remoteOrders"); // Get an UpdateResultSet for the remoteOrders table. UpdateResultSet update_rs = u_table.getUpdates(); // (Continued...) |
更新ごとに、中央データソースの現在の値を取得します。
次の例では、UpdateResultSet の getInt メソッドが、プライマリキーカラム (先頭カラム) の整数値を返します。getMyCentralData メソッドを実装し、使用することにより、中央データソースからデータを取得できます。
while( update_rs.next() ) { // Get central data source values. // Get the primary key value. int pk_value = update_rs.getInt(1); // Get central data source values. int central_value = getMyCentralData(pk_value); // (Continued...) |
更新ごとに、Mobile Link クライアントによってアップロードされた古い値と新しい値を取得します。
次の例では、UpdateResultSet の setOldRowValues と setNewRowValues を使用して、それぞれ古い値と新しい値を取得しています。
// Set mode for old row values. update_rs.setOldRowValues(); // Get the _old_ stored value on the remote. int old_value = update_rs.getInt(2); // Set mode for new row values. update_rs.setNewRowValues(); // Get the _new_ updated value on the remote. int new_value = update_rs.getInt(2); // (Continued...) |
更新ごとに、競合がないかどうかを確認します。
古いロー値が中央データソースの現在の値と一致しない場合、競合になります。競合を解決するため、ビジネス論理を使用して解決後の値を計算します。競合がなかった場合、中央データソースは新しいリモート値で更新されます。setMyCentralData メソッドを実装し、使用することにより、更新を実行します。
// Check if there is a conflict. if(old_value == central_value) { // No conflict. setMyCentralData(pk_value, new_value); } else { // Handle the conflict. int inventory = old_value - new_value; int resolved_value = central_value - inventory; setMyCentralData(pk_value, resolved_value); } } |
handle_UploadData 接続イベント用のメソッドを登録します。
たとえば、次のストアドプロシージャコールは、スクリプトバージョン ver1 を同期するときに、handle_UploadData 接続イベントに対して HandleUpload という .NET メソッドを登録します。Mobile Link 統合データベースに対してこのストアドプロシージャを実行します。
call ml_add_dnet_connection_script( 'ver1', 'handle_UploadData', 'MyScripts.OrderProcessor.HandleUpload' ) |
同期イベント用のメソッド登録の詳細については、次の項を参照してください。
アップロード内のテーブルの UpdateDataReader を取得します。
MyScripts.OrderProcessor.HandleUpload メソッドは、remoteOrders テーブルの UpdateResultSet を取得します。
// method for handle_UploadData event public void HandleUpload( UploadData u_data ) { // Get UploadedTableData for the remoteOrders table. UploadedTableData u_table = u_data.GetUploadedTableByName("remoteOrders"); // Get an UpdateDataReader for the remoteOrders table. UpdateDataReader update_dr = u_table.GetUpdates(); // (Continued...) |
更新ごとに、中央データソースの現在の値を取得します。
次の例では、UpdateDataReader の GetInt32 メソッドが、プライマリキーカラム (先頭カラム) の整数値を返します。getMyCentralData メソッドを実装し、使用することにより、中央データソースからデータを取得できます。
while( update_dr.Read() ) { // Get central data source values. // Get the primary key value. int pk_value = update_dr.GetInt32(0); // Get central data source values. int central_value = getMyCentralData(pk_value); // (Continued...) |
更新ごとに、Mobile Link クライアントによってアップロードされた古い値と新しい値を取得します。
次の例では、UpdateResultSet の setOldRowValues と setNewRowValues を使用して、それぞれ古い値と新しい値を取得しています。
// Set mode for old row values. update_dr.SetOldRowValues(); // Get an _old_ value. int old_value = update_dr.GetInt32(1); // Set mode for new row values. update_dr.SetNewRowValues(); // Get the _new_ updated value. int new_value = update_dr.GetInt32(1); // (Continued...) |
更新ごとに、競合がないかどうかを確認します。
古いロー値が中央データソースの現在の値と一致しない場合、競合になります。競合を解決するため、ビジネス論理を使用して解決後の値を計算します。競合がなかった場合、中央データソースは新しいリモート値で更新されます。setMyCentralData メソッドを実装し、使用することにより、更新を実行します。
// Check if there is a conflict. if(old_value == central_value) { // No conflict. setMyCentralData(pk_value, new_value); } else { // Handle the conflict. int inventory = old_value - new_value; int resolved_value = central_value - inventory; setMyCentralData(pk_value, resolved_value); } } |
![]() |
DocCommentXchange で意見交換できます
|
Copyright © 2013, SAP AG or an SAP affiliate company. - SAP Sybase SQL Anywhere 16.0 |