1

我有一个应用程序 (vb.net),它从用户那里收集数据并将数据本地存储在他们的笔记本电脑上,直到他们将其与中央 SQLServer 2008 数据库同步。同步需要在两个方向上。所以现在,我在每条记录上都有一个时间戳,该时间戳在该记录更新时设置。然后我比较记录上的时间,看看哪个是最近的。如果笔记本电脑上的记录比中央数据库上的记录更新,则笔记本电脑记录被发送。如果中央数据库上的记录比笔记本电脑更新,则该记录将被发送到笔记本电脑。

我有几十万条记录分布在大约 15 个表中。如果您在网络上,则需要 3 到 4 分钟才能完成所有这些操作。对于远程用户来说,问题确实变得更糟。同步需要 20 到 30 分钟。通过 VPN。

我有大约 5 个用户这样做,他们都需要通过中央数据库相互维护相同的信息。它们都同步到中央数据库,而不是彼此同步。

除了比较时间戳之外,还有更好的方法来检查每条记录吗?

  • 请注意,每次同步时只有少数记录 (5%) 发生变化,但我不知道可能是哪些记录。可以是其中任何一个。所以我必须检查所有这些。

谢谢。

4

1 回答 1

1

在我看来,时间戳不是确定将哪些记录发送给另一方的方法。

尽管它们对于解决冲突可能是“可以的”,但同步方(计算机)的时间差异可能会导致记录被跳过发送出去,从而导致真正的问题。

我自己在一个特定的表上使用标识列(在服务器端)来生成序列 nr,并且在每个事务中,我得到一个新的序列号,并将其分配给需要同步的其他表的所有更新/插入的行。

现在,当客户端请求同步时,它会向服务器提供上次同步期间收到的最新“序列”,如果是第一次,则为 0。

服务器将仅发送具有更大序列号的那些记录,然后确定它实际发送给客户端的那些记录上的最高序列号,并将此编号提供给客户端以进行下一次同步请求。

在我的场景中,冲突解决是在客户端完成的,因为所有业务逻辑都是他们的,这意味着客户端总是先接收更新,然后再开始发送他们的。

因为您为每个事务使用一个新生成的序列号,所以您在每次同步期间都保持引用完整性,但要确保这确实是真的,您需要在开始发送同步数据之前确定当前最高的序列号,并且永远不要检索任何记录高于这个数字,否则你可能会破坏参照完整性。

这是因为,在您已经查找了 Orders 而不是 OrderItems 之后,其他一些线程可能已经提交了 Orders 和 OrderItems 的插入,由此您的外向同步包中有 OrderItems 而没有 Order。

对于删除,我使用 IsDeleted 列,服务器会在记录真正被删除之前保存一段时间。

当客户插入数据时,我会给他们反馈哪些(主)键记录了给定的位置,等等……等等。

好吧,我可以在这里提到的还有很多,但这里有一些重要的想法,你应该仔细观察:

如何预防:

  • 缺失记录
  • 缺少删除
  • 双刀片
  • 不必要的记录发送(我使用可为空的字段 LastModifierId)
  • 输入验证
  • 参照完整性
  • 解决冲突
  • 性能成本(选择正确的索引,过滤的唯一索引非常适合跟踪记录的临时客户端插入标识,因此它们也可能为空,您需要这些以防止重复插入)

祝你好运,希望这能给人以思考。

于 2013-11-07T18:01:02.483 回答