在向统一数据库上载行时会发生冲突。如果两个用户修改不同远程数据库中相同的行,则当这两行中的第二行到达 MobiLink 服务器时会检测到冲突。使用同步脚本可以检测和解决冲突。
假定有两个客户同时销售 10 件货品。第一个客户卖出 3 件,因此将更新其客户端数据库 (remote1) 的库存,以表明剩余 7 件。该数据库随后与统一数据库 (mlmon_db) 进行同步。然后,第二个客户卖出 4 件,因此将更新其远程数据库 (remote2) 的库存,以表明剩余 6 件。当后者尝试与 mlmon_db 同步时,会由于库存值已改变而检测到冲突。
必须获取以下行值,以通过编程方式解决此冲突:
统一数据库中的当前值。
remote1 同步后,统一数据库中的值为 7。
remote2 数据库上载的新行值。
remote2 数据库在上一次同步期间获取的旧行值。
可使用以下业务逻辑来计算新的库存值并解决冲突:
当前统一数据库 -(旧远程数据库 - 新远程数据库),即 7 - (10-6) = 3 |
(旧远程数据库 - 新远程数据库)表达式提供了第二个客户卖出的货品数,而非绝对库存值。
添加以下脚本检测和解决冲突:
upload_fetch 可使用此脚本从统一数据库的表中读取行,以进行冲突检测。
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 表事件。
upload_delete 可使用此脚本处理从远程数据库删除的行。对于本教程,需将 MobiLink 服务器设置为忽略此事件。
resolve_conflict 解决冲突脚本应用业务逻辑来解决冲突。
有关 resolve_conflict 的详细信息,请参见resolve_conflict 表事件。
使用 Interactive SQL 连接到数据库。
可以从 Sybase Central 或命令提示符启动 Interactive SQL。
要从 Sybase Central 启动 Interactive SQL,请右击 MLconsolidated - DBA 数据库,然后单击 [打开 Interactive SQL]。
若要在命令提示符下启动 Interactive SQL,请运行以下命令:
dbisql -c "dsn=mlmon_db" |
安装冲突检测和解决脚本。
运行以下 SQL 脚本:
/* upload_fetch */ CALL ml_add_table_script( 'ver1', 'Product', 'upload_fetch', 'SELECT name, quantity FROM Product WHERE name = {ml r.name}' ); /* upload_update */ CALL ml_add_table_script( 'ver1', 'Product', 'upload_update', 'UPDATE Product SET quantity = {ml r.quantity}, last_modified = now() WHERE name = {ml r.name}' ); /* upload_old_row_insert */ CALL ml_add_table_script( 'ver1', 'Product', 'upload_old_row_insert', 'INSERT INTO Product_old (name,quantity,last_modified) VALUES ({ml r.name}, {ml r.quantity}, now())'); /* upload_new_row_insert */ CALL ml_add_table_script( 'ver1', 'Product', 'upload_new_row_insert', 'INSERT INTO Product_new (name,quantity,last_modified) VALUES ({ml r.name}, {ml r.quantity}, now())'); /* upload_delete */ CALL ml_add_table_script( 'ver1', 'Product', 'upload_delete', '--{ml_ignore}'); /* 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'); COMMIT |
在本教程中,MobiLink 服务器通过指定的 -zf 选项运行,使得服务器能够在同步期间检测到任何添加到统一数据库的新脚本。除非指定此选项,否则必须停止 MobiLink 服务器,才能将新脚本添加到统一数据库;在添加新脚本后,请重新启动服务器。
有关 MobiLink 冲突检测和解决的详细信息,请参见冲突处理和检测冲突。
有关 MobiLink 统一数据库的详细信息,请参见MobiLink 统一数据库。
![]() |
使用DocCommentXchange 讨论此页。
|
版权 © 2010, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.0 |