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-Servertechnologie verwenden » Synchronisationsmethoden » Konfliktbehandlung » Konflikte auflösen

 

Konflikte mit upload_update-Skripten lösen

Anstelle des Skripts resolve_conflict können Sie im upload_update-Skript eine gespeicherte Prozedur für die Konfliktlösung verwenden. Bei dieser Methode müssen Sie Konflikte programmtechnisch erkennen und lösen.

Die gespeicherte Prozedur muss das Format des Skripts upload_update mit einer WHERE-Klausel verwenden, die alle Spalten mit Ausnahme der Pre-Image-Werte (alt) enthält.

Das upload_update-Skript kann wie folgt aussehen:

{CALL UpdateProduct(
   {ml o.id}, {ml o.name}, {ml o.desc}, {ml r.name}, {ml r.desc}
)
}

Die gespeicherte Prozedur UpdateProduct kann wie folgt aussehen:

CREATE PROCEDURE UpdateProduct( 
  @id INTEGER,
  @preName VARCHAR(20), 
  @preDesc VARCHAR(200),
  @postName VARCHAR(20), 
  @postDesc VARCHAR(200) ) 
BEGIN
    UPDATE product
     SET name = @postName, description = @postDesc
     WHERE id = @id
       AND name = @preName
       AND description = @preDesc
    IF @@rowcount=0 THEN
        // A conflict occurred: handle resolution here.
    END IF
END

Diese Methode ist häufig einfacher zu verwalten als das Lösen von Konflikten mit resolve_conflict-Skripten, da nur ein Skript gepflegt und verwaltet werden muss und die gesamte Programmlogik in einer gespeicherten Prozedur enthalten ist. Der Code der gespeicherten Prozedur kann jedoch komplizierter sein, wenn die Tabellenspalten NULL oder BLOBs/CLOBs enthalten. Zudem gibt es bei einigen RDBMS, die von konsolidierten MobiLink-Datenbanken unterstützt werden, Einschränkungen bezüglich der Größe der Werte, die an gespeicherte Prozeduren übergeben werden können.

Weitere Hinweise finden Sie unter:

Beispiel

Die folgende gespeicherte Prozedur sp_update_my_customer enthält Programmlogik für die Erkennung und Lösung von Konflikten. Sie akzeptiert alte und neue Spaltenwerte. Dieses Beispiel verwendet SQL Anywhere-Funktionen. Das Skript kann wie folgt implementiert werden:

{CALL sp_update_my_customer(
   {ml o.cust_1st_pk},
   {ml o.cust_2nd_pk},
   {ml o.first_name},
   {ml o.last_name},
   {ml o.nullable_col},
   {ml o.last_modified},
   {ml r.first_name},
   {ml r.last_name},
   {ml r.nullable_col},
   {ml r.last_modified}
)} 
CREATE PROCEDURE sp_update_my_customer(
     @cust_1st_pk        INTEGER,
     @cust_2nd_pk        INTEGER,
     @old_first_name     VARCHAR(100),
     @old_last_name      VARCHAR(100),
     @old_nullable_col   VARCHAR(20),
     @old_last_modified  DATETIME,  
     @new_first_name     VARCHAR(100),
     @new_last_name      VARCHAR(100),
     @new_nullable_col   VARCHAR(20),
     @new_last_modified  DATETIME
) 
BEGIN
DECLARE @current_last_modified DATETIME;
// Detect a conflict by checking the number of rows that are
// affected by the following update. The WHERE clause compares
// old values uploaded from the remote to current values in
// the consolidated database. If the values match, there is
// no conflict. The COALESCE function returns the first non-
// NULL expression from a list, and is used in this case to
// compare values for a nullable column.


UPDATE my_customer
SET first_name                  = @new_first_name,
 last_name                      = @new_last_name,
 nullable_col                   = @new_nullable_col,
 last_modified                  = @new_last_modified

WHERE cust_1st_pk               = @cust_1st_pk
 AND cust_2nd_pk                = @cust_2nd_pk
 AND first_name                 = @old_first_name
 AND last_name                  = @old_last_name
 AND COALESCE(nullable_col, '') = COALESCE(@old_nullable_col, '')
 AND last_modified              = @old_last_modified;
... 
// Use the @@rowcount global variable to determine
// the number of rows affected by the update. If @@rowcount=0,
// a conflict has occurred. In this example, the database with
// the most recent update wins the conflict. If the consolidated
// database wins the conflict, it retains its current values
// and no action is taken.

IF( @@rowcount = 0 ) THEN
// A conflict has been detected. To resolve it, use business
// logic to determine which values to use, and update the
// consolidated database with the final values.

  SELECT last_modified INTO @current_last_modified
     FROM my_customer WITH( HOLDLOCK )
     WHERE cust_1st_pk=@cust_1st_pk
        AND cust_2nd_pk=@cust_2nd_pk;

     IF( @new_last_modified > @current_last_modified ) THEN
     // The remote has won the conflict: use the values it
     // uploaded.
  
       UPDATE my_customer
       SET first_name    = @new_first_name,
         last_name     = @new_last_name,
         nullable_col  = @new_nullable_col,
         last_modified = @new_last_modified
       WHERE cust_1st_pk  = @cust_1st_pk
          AND cust_2nd_pk   = @cust_2nd_pk;
       
     END IF;
END IF;
END;

Weitere Hinweise finden Sie unter: