Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (Deutsch) » MobiLink - Serveradministration » MobiLink-Server-APIs » Direkte Zeilenbehandlung » Direkte Uploads verarbeiten

 

Konfliktverarbeitung für direkte Uploads

Sendet ein MobiLink-Client eine aktualisierte Zeile an den MobiLink-Server, so enthält diese Zeile nicht nur die aktualisierten Werte (die Post-Image-Zeile), sondern auch eine Kopie der Werte der alten Zeile (Pre-Image-Zeile oder alte Zeile) aus der letzten Synchronisation mit dem MobiLink-Server. Wenn die Pre-Image-Zeile nicht mit den aktuellen Werten in Ihrer zentralen Datenquelle übereinstimmt, wird ein Konflikt festgestellt.

SQL-basierte Konfliktlösung

Bei SQL-basierten Uploads ist die konsolidierte MobiLink-Datenbank Ihre zentrale Datenquelle, und MobiLink stellt spezielle Ereignisse für die Konflikterkennung und -lösung bereit.

Weitere Hinweise finden Sie unter Konfliktbehandlung.

Konfliktlösung mit der direkten Zeilenbehandlung

Bei direkten Uploads können Sie zur Konflikterkennung über Programme auf neue und alte Zeilen zugreifen.

UpdateResultSet (von der Methode UploadedTableData.getUpdates geliefert) erweitert die Standardergebnismengen von Java oder .NET so, dass diese spezielle Methoden zum Bearbeiten von Konflikten umfassen. setNewRowValues stellt UpdateResultSet so ein, das neue aktualisierte Werte von einem entfernten Client zurückgegeben werden (Standardmodus). setOldRowValues stellt UpdateResultSet so ein, dass alte Zeilenwerte zurückgegeben werden.

Konflikte mit der direkten Zeilenbehandlung erkennen

Bei der Verwendung der UpdateResultSet-Methode .setOldRowValues erhalten Sie die Werte einer Zeile in der entfernten Datenbank vor ihrer Änderung. Sie vergleichen die zurückgegebenen Zeilenwerte mit den vorhandenen Zeilenwerten in Ihrer Datenquelle. Wenn die verglichenen Zeilen nicht gleich sind, liegt ein Konflikt vor.

Konflikte mit der direkten Zeilenbehandlung lösen

Wenn Sie einen Konflikt während eines Uploads erkannt haben, können Sie benutzerdefinierte Geschäftslogik verwenden, um ihn aufzulösen. Die Lösung wird von Ihrem Java- oder .NET-Code verarbeitet.

Beispiel

Angenommen, Sie protokollieren den Lagerbestand in einem XML-Dokument und möchten das Dokument als zentrale Datenquelle verwenden. Benutzer1 verwendet eine Ihrer entfernten Datenbanken namens Remote1. Benutzer2 verwendet eine andere entfernte Datenbank namens Remote2.

Ihr XML-Dokument, Benutzer1 und Benutzer2 starten jeweils mit einem Lager, das zehn Artikel umfasst. Benutzer1 verkauft drei Artikel und aktualisiert den Lagerwert von Remote1 auf sieben Artikel. Benutzer2 verkauft vier Artikel und aktualisiert das Lager von Remote2 auf sechs Artikel. Wenn Remote1 synchronisiert, wird die zentrale Datenbank auf sieben Artikel aktualisiert. Wenn Remote2 synchronisiert, wird ein Konflikt festgestellt, da der Wert des Lagers nicht mehr zehn Artikel ist. Um diesen Konflikt programmatisch zu lösen, benötigen Sie drei Zeilenwerte:

  • Den aktuellen Wert in der zentralen Datenquelle

  • Den neuen Zeilenwert, den Remote2 ausgelesen hat

  • Den alten Zeilenwert, den Remote2 bei der letzten Synchronisation erhalten hat

In diesem Fall würde die Geschäftslogik folgende Berechnung verwenden, um den neuen Lagerwert zu ermitteln und den Konflikt zu lösen:

current data source - (old remote - new remote)
-> 7 - (10-6) = 3

Die nachfolgenden Prozeduren für Java und .NET zeigen, wie Sie diesen Konflikt für direkte Uploads lösen können. Die gezeigte Tabelle dient dabei als Beispiel:

CREATE TABLE remoteOrders
(
    pk integer primary key not null,
    inventory integer not null
);
♦  So verarbeiten Sie direkte Konflikte (Java)
  1. Registrieren Sie eine Java-Methode für das Verbindungsereignis handle_UploadData.

    Weitere Hinweise finden Sie unter handle_UploadData (Verbindungsereignis).

    Die folgende gespeicherte Prozedur registriert beispielsweise eine Java-Methode namens HandleUpload für das Verbindungsereignis handle_UploadData, wenn die Skriptversion ver1 synchronisiert wird. Sie führen diese gespeicherte Prozedur für Ihre konsolidierte MobiLink-Datenbank aus.

    call ml_add_java_connection_script( 'ver1',
       'handle_UploadData',
       'OrderProcessor.HandleUpload' )

    Weitere Hinweise zum Registrieren von Methoden für Synchronisationsereignisse finden Sie unter:

  2. Rufen Sie UpdateResultSet für eine Tabelle im Upload ab.

    Die Methode OrderProcessor.HandleUpload gibt UpdateResultSet für die remoteOrders-Tabelle zurück.

    // 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...)
  3. Rufen Sie für jede Aktualisierung die aktuellen Werte in Ihrer zentralen Datenquelle ab.

    In diesem Beispiel gibt die Methode UpdateResultSet getInt einen Ganzzahlwert für die Primärschlüsselspalte (die erste Spalte) zurück. Sie können die Methode getMyCentralData implementieren und anschließend mit ihr Daten aus Ihrer zentralen Datenquelle abrufen.

    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...)
  4. Rufen Sie für jede Aktualisierung die alten und die neuen Werte ab, die der MobiLink-Client hochgeladen hat.

    Im Beispiel werden UpdateResultSet setOldRowValues und UpdateResultSet setNewRowValues für alte bzw. neue Werte verwendet.

      // 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...)
  5. Überprüfen Sie jede Aktualisierung auf Konflikte.

    Ein Konflikt liegt vor, wenn der alte Zeilenwert nicht mit dem aktuellen Wert in der zentralen Datenquelle übereinstimmt. Um den Konflikt zu lösen, wird unter Verwendung der Geschäftslogik ein gelöster Wert berechnet. Tritt kein Konflikt auf, wird die zentrale Datenquelle mit dem neuen entfernten Wert aktualisiert. Sie können die Methode setMyCentralData implementieren und anschließend mit ihr die Aktualisierung ausführen.

      // 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);
    
      }
    }
♦  So verarbeiten Sie direkte Konflikte (.NET)
  1. Registrieren Sie eine Methode für das Verbindungsereignis handle_UploadData.

    Die folgende gespeicherte Prozedur registriert beispielsweise eine .NET-Methode namens HandleUpload für das Verbindungsereignis handle_UploadData, wenn die Skriptversion ver1 synchronisiert wird. Sie führen diese gespeicherte Prozedur für Ihre konsolidierte MobiLink-Datenbank aus.

    call ml_add_dnet_connection_script( 'ver1',
       'handle_UploadData',
       'MyScripts.OrderProcessor.HandleUpload' )

    Weitere Hinweise zum Registrieren von Methoden für Synchronisationsereignisse finden Sie unter:

  2. Rufen Sie UpdateDataReader für eine Tabelle im Upload ab.

    Die Methode MyScripts.OrderProcessor.HandleUpload ruft ein UpdateResultSet für die Tabelle remoteOrders ab:

    // 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...)
  3. Rufen Sie für jede Aktualisierung die aktuellen Werte in Ihrer zentralen Datenquelle ab.

    In diesem Beispiel gibt die Methode UpdateDataReader GetInt32 einen Ganzzahlwert für die Primärschlüsselspalte (die erste Spalte) zurück. Sie können die Methode getMyCentralData implementieren und anschließend mit ihr Daten aus Ihrer zentralen Datenquelle abrufen.

    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...)
  4. Rufen Sie für jede Aktualisierung die alten und die neuen Werte ab, die der MobiLink-Client hochgeladen hat.

    Im Beispiel werden UpdateResultSet setOldRowValues und UpdateResultSet setNewRowValues für alte bzw. neue Werte verwendet.

      // 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...)
  5. Überprüfen Sie jede Aktualisierung auf Konflikte.

    Ein Konflikt liegt vor, wenn der alte Zeilenwert nicht mit dem aktuellen Wert in der zentralen Datenquelle übereinstimmt. Um den Konflikt zu lösen, wird unter Verwendung der Geschäftslogik ein gelöster Wert berechnet. Tritt kein Konflikt auf, wird die zentrale Datenquelle mit dem neuen entfernten Wert aktualisiert. Sie können die Methode setMyCentralData implementieren und anschließend mit ihr die Aktualisierung ausführen.

      // 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);
    
      }
    }