在 MobiLink 客户端向 MobiLink 服务器发送一个更新后的行时,发送的数据中不仅包含更新后的值(后映像或新行),而且还将包含那些上次与 MobiLink 服务器同步时获得的旧行值的副本(前映像或旧行)。如果前映像行与中央数据源中的当前值不匹配,表示检测到了冲突。
对于基于 SQL 的上载,MobiLink 统一数据库是您的中央数据源,并且 MobiLink 为冲突的检测和解决提供了特殊事件。
请参见冲突处理。
对于直接上载,可以编程方式访问新旧行以便冲突的检测和解决。
UpdateResultSet(由 UploadedTableData.getUpdates 方法返回)扩展标准 Java 或 .NET 结果集以包括处理冲突的特殊方法。setNewRowValues 设置 UpdateResultSet 以从远程客户端返回新的更新后的值(缺省模式)。setOldRowValues 设置 UpdateResultSet 以返回旧行值。
通过使用 UpdateResultSet 方法 .setOldRowValues,在远程某行的值被更改之前获取该行的值。将返回的行值与数据源中的现有行值进行比较。如果比较的行不相等,则存在冲突。
一旦在上载期间检测到冲突,您可以使用自定义业务逻辑来解决冲突。冲突的解决通过 Java 或 .NET 代码进行处理。
假定您在 XML 文档中跟踪库存并想要将其用作中央数据源。User1 使用您的远程数据库中名为 Remote1 的数据库。User2 使用名为 Remote2 的另一远程数据库。
您的 XML 文档、User1 和 User2 开始时的库存都为 10 件。User1 卖出 3 件并将 Remote1 的库存值更新为 7 件。User2 卖出 4 件并将 Remote2 的库存更新为 6 件。当 Remote1 同步时,中央数据库将被更新为 7 件。Remote2 同步时,由于库存值不再是 10 个项目,因此会检测到冲突。若要以编程方式解决这一冲突,需要三个行值:
中央数据源中的当前值。
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 或 .NET 方法。
例如,以下存储过程调用在同步脚本版本 ver1 时,为 handle_UploadData 连接事件注册一个称为 HandleUpload 的 Java 方法。针对您的 MobiLink 统一数据库运行此存储过程。
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...) |
针对每次更新,获取由 MobiLink 客户端上载的旧值和新值。
该示例分别将 UpdateResultSet setOldRowValues 和 UpdateResultSet 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 方法。针对您的 MobiLink 统一数据库运行此存储过程。
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...) |
针对每次更新,获取由 MobiLink 客户端上载的旧值和新值。
该示例分别将 UpdateResultSet setOldRowValues 和 UpdateResultSet 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 讨论此页。
|
版权 © 2010, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.0 |