2009-06-02 97 views
2

这是场景。我有一个Oracle统一数据库。我正在使用Mobilink将Oracle与正在手持设备上使用的SqlAnywere数据库进行同步。 如果userA将其手持设备上的远程数据库中的记录更改为“更新第一”,然后10分钟后userB将其手持设备上的相同记录更新为“更新第二”,我希望统一数据库始终显示“更新第二”两台设备同步后。目前,如果userB在userA之前同步,统一数据库将读取“首先更新”。如何让Mobilink同步表以便最新更新的表不被覆盖?

回答

4

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

这将需要两件事情在远程数据库发生:

1)将需要在那个同步,将跟踪记录被更新时统一数据库的远程数据库表中的列在远程站点。 2)你将不得不信任远程站点的系统时钟。如果人们知道如何解决冲突,并希望确保他们的数据赢得冲突,那么没有什么能够阻止用户将其远程设备上的系统时间更改为下周,更新其数据,将系统时间更改回来以及然后同步。

在合并时,您需要实施冲突解决方案,但这并不困难。只要您的表格不包含任何斑点,您可以在表格的upload_update事件中编写冲突解决方案。让我们假设一个表中,看起来像远程数据库:

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 
); 

我们还要在这个看起来非常相似,合并假设表,但也有另一种最后修改列时排在巩固已更改为跟踪。

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事件将看起来是这样的:

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事件,调用存储过程,并在旧行值也从传远程数据库。

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子句将包括主键值,并从远程数据库中的旧行值。如果有人更改了联合的行,此更新将更新零行,并且我们知道发生了冲突。如果它更新了一行,那么就没有冲突。存储过程会是这个样子(以下伪SQL):

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

+0

会发生什么?我想要更新远程数据库以匹配整合。我该如何去做或者是默认行为? – 2009-06-03 20:31:15

2

假设你已经实现了基于时间戳下载或快照下载,那么遥控器将被更新,以匹配合并,如果合并自上次同步由另一个远程已更新。

顺便说一句,你要解决冲突的类型,若您设置了同步模式(http://dcx.sybase.com/index.php#http%3A%2F%2Fdcx.sybase.com%2Fhtml%2Fdbmgen10%2Fmg-mg-about-s-5060632a.html),在10版及更高版本。无论是在创建同步模型向导,或在映射页创建模型后,您可以选择是否要基于行或基于列的冲突检测,以及不同类型的冲突解决。你想要什么对应于“时间戳”冲突解决选项,你选择一个现有的时间戳列。

仅供参考,向导解释了这些选项超过映射页,所以我建议先探索在向导的那些选项。请注意,如果“较新的使用您维护的时间戳列”选项呈灰色,则表示同步的表中没有时间戳列。

一旦你创建了一个模型,你可以预览在活动页面上生成的脚本。完成模型设置后,将其部署到创建SQL和批处理文件和/或直接将SQL应用于数据库。如果随upload_update事件没有更新统一数据库