首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何让Mobilink同步表,使最新更新的表不被覆盖?

如何让Mobilink同步表,使最新更新的表不被覆盖?
EN

Stack Overflow用户
提问于 2009-06-02 20:47:55
回答 2查看 1.1K关注 0票数 2

这是一个场景。我有一个Oracle统一数据库。我正在使用Mobilink将Oracle与手持设备上正在使用的SqlAnywere数据库进行同步。如果userA将其手持设备上的远程数据库中的记录更改为“先更新”,然后10分钟后,userB将其手持设备上的相同记录更新为“已更新秒”,我希望统一数据库在两个设备同步后始终显示“已更新秒”。目前,如果userB在userA之前同步,则统一数据库将显示为“更新优先”。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-06-03 14:24:00

现在,您正在使用MobiLink服务器中的默认冲突解决方案,因此默认情况下,wins中的最后一个同步。您需要实现自己的冲突解决方案来处理此问题。

这将要求在远程数据库中发生两件事:

1)远程数据库的表中需要有一个与统一数据库同步的列,用于跟踪在远程站点更新记录的时间。

2)您必须信任远程站点的系统时钟。如果人们弄清楚冲突是如何解决的,并希望确保他们的数据赢得冲突,那么没有什么可以阻止用户将其远程设备上的系统时间更改为下周,更新其数据,将系统时间往回更改,然后进行同步。

在合并后,您将需要实现冲突解决,这并不难。只要您的表不包含任何blobs,您就可以在表的upload_update事件中编写冲突解决方案。让我们假设远程数据库中有一个表,如下所示:

代码语言:javascript
复制
create table Admin (
  admin_id           bigint default global autoincrement(1000000) primary key,
  data               varchar(64) not null,
  rem_last_modified  timestamp not null default timestamp
);

我们还假设统一数据库中有一个表,该表看起来非常相似,但也有另一个最后修改过的列,用于跟踪合并数据库中的行何时发生了更改。

代码语言:javascript
复制
create table Admin (
  admin_id           bigint default global autoincrement(1000000) primary key,
  data               varchar(64) not null ,
  rem_last_modified  timestamp not null default ‘1900-01-01’,
  cons_last_modified timestamp default timestamp
);

通常,您的upload_update事件将如下所示:

代码语言:javascript
复制
call ml_add_table_script( 'v1', 'Admin', 'upload_update',
'update Admin set data = {ml r.data}, 
              rem_last_modified = {ml r.rem_last_modified}  
 where admin_id = {ml r.admin_id}'
);

相反,我们将重写upload_update事件以调用存储过程,并从远程数据库传入旧的行值。

代码语言:javascript
复制
call ml_add_table_script( 'v1', 'Admin', 'upload_update',
'call admin_upload_update( {ml r.admin_id}, 
    {ml r.data}, {ml r.rem_last_modified}, 
    {ml o.data}, {ml o.rem_last_modified}’
);

存储过程的关键是我们将执行更新,但是更新的where子句将包括来自远程数据库的主键值和旧行值。如果有人在consoliated中更改了行,此更新将更新零行,我们知道会发生冲突。如果它更新了一行,那么就没有冲突。您的存储过程将如下所示(下面是伪SQL):

代码语言:javascript
复制
create procedure admin_upload_update ( 
    @admin_id bigint, 
    @new_data varchar(64), 
    @new_rem_lmod timestamp,
    @old_data varchar(64), 
    @old_rem_lmod timestamp 
)
begin
    declare @cur_rem_lmod timestamp;
    update admin set data = @new_data, rem_last_modified = @new_rem_lmod
     where admin_id = @admin_id 
       and data = @old_data 
       and rem_last_modified = @old_rem_lmod;
    if @@rowcount = 0 then
        // conflict !!
        select rem_last_modified into @cur_rem_lmod 
          from admin where admin_id = @admin_id;
        if @new_rem_lmod > @cur_rem_lmod then
            // update using new_data and new_rem_lmod
        else 
            // do nothing, current values in cons wins
        end if;
    end if;  
end;

有关冲突解决的更多信息,请参阅v10文档的以下部分:

MobiLink -服务器管理

同步技术

处理冲突

http://dcx.sybase.com/index.php#http%3A%2F%2Fdcx.sybase.com%2Fhtml%2Fdbmlen10%2Fml-conflicts-synch.html

票数 4
EN

Stack Overflow用户

发布于 2009-06-04 14:10:10

假设您已经实施了基于时间戳的下载或快照下载,如果自上次同步以来,另一个远程更新了合并的内容,则远程服务器将进行更新以匹配整合的内容。

顺便说一句,如果您设置了一个同步模型(http://dcx.sybase.com/index.php#http%3A%2F%2Fdcx.sybase.com%2Fhtml%2Fdbmgen10%2Fmg-mg-about-s-5060632a.html),您需要的冲突解决类型是可用的,该模型在版本10和更高版本中可用。在创建同步模型向导中,或在创建模型后的映射页中,可以选择是基于行还是基于列的冲突检测以及不同类型的冲突解决方案。您需要的内容与" timestamp“冲突解决方案选项相对应,您可以从中选择一个现有的时间戳列。

仅供参考,向导对选项的解释多于对映射页面的解释,因此我建议您首先在向导中浏览这些选项。请注意,如果"Newer wins,using A timestamp column,using you column“选项呈灰色显示,则表示同步表中没有时间戳列。

一旦创建了模型,您就可以在Events页面中预览生成的脚本。在完成模型设置后,您可以部署它以创建SQL和批处理文件和/或将SQL直接应用于数据库。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/941835

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档