这些业务对象可以在双方都进行编辑、删除和更新。双方都可以在本地存储对象,但仅在iPhone侧为断开视图启动同步。所有对象都有一个updated_at和created_at时间戳,并且在两侧都由RDBMS支持(iPhone侧为SQLite,Web侧为MySQL...我认为这并不重要),手机记录了上次尝试同步的时间。否则,没有其他数据被存储(目前)。
你会使用什么算法来最小化系统之间的网络聊天同步?如果“软删除”不是一个选项,你将如何处理删除?你会添加哪些数据模型更改来促进这一点?
最简单的方法:同步时传输所有记录,其中更新时间 >= @last_sync_at
。缺点是这种方法不能很好地容忍时钟偏差。
可能更安全的方法是保留一个版本号列,每次更新行时递增它(以防止时钟偏差破坏同步过程),并保留一个上次同步的版本号(以便识别潜在的冲突更改)。为了使带宽高效,每个数据库都要保留一个缓存,包含发送给每个复制同伴的上一个版本,因此只需要传输修改的行。如果这将是一个星形拓扑结构,则叶子可以使用简化的模式,在每个表中存储上次同步的版本。
为了支持删除同步,需要某种形式的软删除,但可以采用“墓碑”记录的形式,其中仅包含已删除行的键。只有确定所有副本都已处理这些记录后,才能安全地删除墓碑,否则滞后的副本可能会复活你认为已被删除的记录。
所以我认为,总的来说,你的问题与断开式同步有关。
这是我认为应该发生的事情:
初始同步:您检索数据及其相关信息(行版本、文件校验和等)。重要的是,您要存储此信息并保持原始状态,直到下一次成功同步。更改应在此数据的副本上进行。
跟踪更改:如果您正在处理数据库行,则基本思想是跟踪插入、更新和删除操作。如果您正在处理像 XML 这样的文本文件,则稍微复杂一些。如果可能会有多个用户同时编辑此文件,则必须具有差异工具,以便可以在更细粒度的级别(而不是整个文件)检测到冲突。
如果您只处理数据库行,则检测冲突易于检测。您可以有另一列,每当更新行时增加(我认为mssql具有此内置功能,不确定mysql是否有)。因此,如果您拥有的副本与服务器上的数字不同,则存在冲突。对于文件或字符串,校验和可以完成工作。我想你也可以使用修改日期,但请确保你有一个非常精确和准确的度量来防止错过。例如:假设我检索了一个文件,而你在我检索它后立即保存了它。假设时间差是1毫秒。然后我对文件进行更改,然后尝试保存它。如果记录的最后修改时间仅准确到10毫秒,那么我检索到的文件很有可能与您保存的文件具有相同的修改日期,因此程序认为没有冲突并覆盖您的更改。因此,我通常不使用这种方法以确保安全。另一方面,在轻微修改后发生校验和/哈希碰撞的可能性接近于零。
解决冲突 现在是棘手的部分。如果这是一个自动化的过程,那么你需要评估情况,并决定是要覆盖更改、丢失你的更改,还是重新从服务器检索数据并尝试重新执行更改。幸运的是,看起来会有人类互动。但编码仍然很麻烦。如果你正在处理数据库行,可以逐个检查每个列,并将其与服务器中的数据进行比较,并呈现给用户。关键是以非常细微的方式向用户展示冲突,以避免给他们造成压力。大多数冲突在许多不同的地方都有非常小的差异,所以一次只向用户展示一处小差异。因此,对于文本文件来说,基本上是相同的,但更加复杂一百倍。所以基本上你需要创建或使用一个差异工具(文本比较是一个完全不同的主题,太广泛了,无法在这里提及),它能告诉你文件中的小改变以及它们在数据库中的位置:文字是插入的、删除的还是编辑的。然后以同样的方式向用户展示。所以基本上对于每个小冲突,用户需要选择是否放弃他们的更改,覆盖服务器上的更改,还是在发送到服务器之前进行手动编辑。