0

我们有一个具有本地数据库的 Windows 应用程序。我们的客户很少要求从其所有位置进行集中报告。我们提出的解决方案是在客户总部通过静态 IP 建立一个中央数据库,并使用 WCF 服务同步所有数据。

由于中央服务器可能并不总是可用,我需要一个简单的解决方案,从每个离线数据库中了解所有未与中央数据库同步的记录。这样后端的定时服务会将所有剩余数据复制到中央数据库。

一种选择是在所有表中都有一个布尔列作为 IsSynched 来表示它是否同步。但这需要在所有引用的程序和代码中进行大量代码更改。

任何替代解决方案?

4

3 回答 3

2

我建议布尔 IsSynced 在同步方面非常非常弱。如果办公室离线的时间更长,您肯定会很难让一切都保持同步。

如果添加列 VersionNumber,您将知道,VersionNumber 低于实际 VersionNumber 的每一行都需要更新。

更复杂的方法可能是将 LastUpdated TimeStamp 列添加到每个表中,这可能会节省一些流量,因为 VersionNumber 可能会增加并且它可能包含行更新,但可能不会!而我看到的 LastUpdated 是特定于行的,它创造了仅获取(=更新)数据(=行)的机会,这些数据比您(=中央)整个数据库中的最新记录更新。这实际上可以像花花公子一样工作。

于 2013-11-17T07:23:20.860 回答
0

有几点需要考虑:

  • 为什么中央数据库不总是可用?
  • 报告是针对中央数据库还是本地数据库执行?
  • 是否需要 2 路同步(本地 <-> 中央)?
  • 同步期间连接的可靠性如何?

我最近继承的一个解决方案通过以下方式处理这个问题:

  • Windows 服务在后台运行——它负责同步。本地应用程序不是。
  • 对于中央 --> 本地同步,每条记录都有一个 last_updated (DateTime) 列。每次更新记录时,它都会更新为 CURRENT_TIMESTAMP。对于本地数据库中的每个表,Windows 服务都会检查最新的记录时间戳。向中央数据库中的相应表发起查询以获取任何新的/更新的记录,例如SELECT * FROM central.table WHERE last_update > @lastLocalUpdate;. 任何结果都会在本地数据库中插入/更新。
  • 对于本地 --> 中央同步,本地数据库中的每条记录只有一个 is_sent (boolean) 列。每次对记录进行本地更新时,此设置为 false。对于本地数据库中的每个表,Windows 服务都会检查尚未发送到中央数据库的记录,即SELECT * FROM local.table WHERE is_sent = 0;. 任何结果都被插入/更新到中央数据库中,然后 is_sent 设置为 1。

这有点健谈,但它最终奏效了。在我的情况下,本地设备经常失去连接,所以这种粒度是有效的。

我的愿望清单上最重要的是彻底改革这个机制并实现一个消息队列。

编辑:如果您坚持不想对现有代码库进行任何更改,则可以在 SQL 级别实现 last_updated / is_sent 更新并进行同步。服务作为一个完全独立的项目。“隐形更新”不会成为最干净的解决方案,但是嘿 - 选择你的战斗。

于 2013-11-17T10:17:15.750 回答
0

听起来您需要实现“多主”或“多源”复制。多主复制是自己实现的一个非常棘手的提议。

我通过以下方式完成了它:您将需要每个表上的触发器(插入、删除、更新),以跟踪对每行所做的所有更改到“更改跟踪”表(您必须确保触发器保留在任何数据库中) /表更新)。更改表将需要一个全局唯一键(通常是唯一“站点代码”和每行唯一 ID 的组合)、更改类型、更改的 UTC 日期/时间、表名称、行 ID 和每行 CRUD 的复制状态(即发送日期)。您将更改跟踪表与 WCF 服务一起使用,以使客户端与服务器表同步。您还需要在启动复制系统之前确保它们包含相同的数据(可能通过在开始时将站点数据库上传到中央数据库)。

如果您可以切换到另一个数据库,最新版本的 MariaDB 会免费提供开箱即用的此功能 ( https://mariadb.com/kb/en/multi-source-replication/ )。数据库级别的这种功能将使这项任务变得相当容易。

或者,根据您的预算和 DBMS,是否有一些现成的复制产品可以帮助您?

于 2013-11-17T09:48:37.420 回答