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

SQL Anywhere 11.0.1 (中文) » MobiLink - 入门 » MobiLink 教程 » 教程:编写脚本和监控同步

 

第 6 课:创建冲突检测和解决脚本

在向统一数据库上载行时会发生冲突。如果两个用户修改不同远程数据库中相同的行,则当这两行中的第二行到达 MobiLink 服务器时会检测到冲突。使用同步脚本可以检测和解决冲突。

有关 MobiLink 冲突解决的详细信息,请参见冲突处理

库存示例

假设在实地有两个销售员的场景。Salesman1 开始时库存有 10 个货品,后来卖出 3 个。他将其远程数据库 remote1 的库存更新为 3 个货品。Salesman2 卖出 4 个货品并将其库存(在 Remote2 上)更新为 6。

当 remote1 使用 MobiLink 同步客户端实用程序进行同步时,统一数据库更新为 7。当 remote2 同步时,将检测到冲突,因为统一数据库中的库存值已更改。

若要以编程方式解决这一冲突,需要三个行值:

  1. 统一数据库中的当前值。

    remote1 同步后,统一数据库中的值为 7。

  2. Remote2 上载的新行值。

  3. Remote2 在上一次同步期间获取的旧行值。

在这种情况下,可使用以下业务逻辑来计算新的库存值并解决冲突:

current consolidated - (old remote - new remote)
that is, 7 - (10-6) = 3

表达式(旧远程数据库 - 新远程数据库)提供了 Salesman2 卖出的货品数,而非绝对库存值。

用于冲突检测和解决的同步脚本

要检测和解决冲突,添加以下脚本:

  • upload_update   upload_update 事件决定应如何将插入到远程数据库的数据应用于统一数据库。也可以使用 upload_update 的扩展原型检测更新冲突。

    有关使用 upload_update 检测冲突的详细信息,请参见检测冲突

    有关 upload_update 的详细信息,请参见upload_update 表事件

  • upload_old_row_insert   使用此脚本处理远程数据库在上一次同步时获取的旧行值。

    有关 upload_old_row_insert 的详细信息,请参见upload_old_row_insert 表事件

  • upload_new_row_insert   使用此脚本处理新行值(远程数据库上的更新值)。

    有关 upload_new_row_insert 的详细信息,请参见upload_new_row_insert 表事件

  • resolve_conflict   解决冲突脚本应用业务逻辑来解决冲突。

    有关 resolve_conflict 的详细信息,请参见resolve_conflict 表事件

♦  安装冲突检测和解决脚本
  1. 启动 Interactive SQL。

    1. 在命令提示符下,键入 dbisql

    2. 单击 [标识] 选项卡。

    3. 在 [用户 ID] 字段键入 DBA

    4. 在 [口令] 字段中键入 sql

    5. 单击 [数据库] 选项卡。

    6. 在 [服务器名] 字段中键入 cons

    7. 单击 [确定]。

  2. 安装冲突检测和解决脚本:

    在 Interactive SQL 中执行以下语句:

    /* upload_update */
    call ml_add_table_script( 'ver1', 'Product',
     'upload_update',
     'UPDATE Product
       SET quantity = ?, last_modified = ?
        WHERE name = ?
        AND quantity=? AND last_modified=?' )
    go
    
    /* upload_old_row_insert */
    call ml_add_table_script( 'ver1', 'Product',
     'upload_old_row_insert',
     'INSERT INTO Product_old (name,quantity,last_modified)
       values (?,?,?)')
    go
    
    /* upload_new_row_insert */
    call ml_add_table_script( 'ver1', 'Product',
     'upload_new_row_insert',
     'INSERT INTO Product_new (name,quantity,last_modified)
       values (?,?,?)')
    go
    
    /* resolve_conflict */
    call ml_add_table_script( 'ver1', 'Product',
     'resolve_conflict',
     'declare @product_name varchar(128);
      declare @old_rem_val integer;
      declare @new_rem_val integer;
      declare @curr_cons_val integer; 
      declare @resolved_value integer;
    
      // obtain the product name
      SELECT name INTO @product_name
         FROM Product_old;
    
      // obtain the old remote value
      SELECT quantity INTO @old_rem_val
        FROM Product_old;
    
      //obtain the new remote value
      SELECT quantity INTO @new_rem_val
        FROM Product_new;
    
      // obtain the current value in cons
      SELECT quantity INTO @curr_cons_val
       FROM Product WHERE name = @product_name;
    
      // determine the resolved value
      SET @resolved_value =
        @curr_cons_val- (@old_rem_val - @new_rem_val);
    
      // update cons with the resolved value
      UPDATE Product
       SET quantity = @resolved_value
       WHERE name = @product_name;
    
      // clear the old and new row tables
      delete from Product_new;
      delete from Product_old
     ')

SQL Anywhere 统一数据库的设置已完成。

进一步阅读

有关 MobiLink 冲突检测和解决的详细信息,请参见冲突处理

有关 MobiLink 统一数据库的详细信息,请参见MobiLink 统一数据库