我有一个支持脱机模式下,用户可以创建一个将与服务器,当用户重新联机同步数据的互联网应用。 如此,因为这个我使用UUID的身份在我的数据库,所以断开的客户端可以不用担心使用其他客户端使用的ID等,但产生的新对象,而这个伟大工程由该用户有拥有的对象是由多个用户共享的对象。 例如,用户使用的标签可能是全球性的,而且也没有可能的方式远程数据库可容纳宇宙中的所有可能的标签。
如果脱机用户创建一个对象,并增加了一些标签给它。 比方说,让软件生成一个UUID为他们这些标签不会在用户的本地数据库中存在。 现在,当这些标签是同步的还有将需要解析过程来解决任何重叠。 某种方式与本地版本的远程数据库匹配任何现有的标记。
一种方法是使用一些方法,通过该全局对象是通过自然键(名字标签的情况下)解决,而本地数据库有可能取代它的现有的对象与来自全球的数据库之一。 当有其他对象的许多连接。这可能是肮脏的。 东西告诉我,避免这种情况。
处理这个另一种方法是使用两个ID。 一个全局ID和一个本地ID。 我用的UUID,将有助于避免这种希望,但我不断来回使用单一的UUID和使用两个分裂ID之间。 使用此选项让我不知道如果我让这个问题变得不可收拾。
另一种方法是跟踪通过非共享对象的所有的变化。 在该示例中,该对象的用户指定的标签。 当用户同步他们的脱机更改服务器可能与全球一个取代他的局部变量。 此客户端同步与服务器的下一次检测到在非共享对象中的变化。 当客户端拉低该对象,他就会收到全球标签。 该软件会简单地重新保存指向服务器的标签和他成为孤儿本地版本的非共享对象。 与此有些问题是额外的往返完全同步,以及额外的数据,这只是孤立的本地数据库。 是当系统处于同步状态之间可能发生的还有其他问题或错误? (即试图说服到服务器并发送其本地的UUID的对象,等)。
另一种选择是避免常见物体。 在我的软件,可能是一个可以接受的答案。 我没有做很多的跨用户对象的共享,但是,这并不意味着我会在未来不那样做。 这意味着选择此选项可以在今后应我需要添加这些类型的功能瘫痪我的软件。 有后果这个选择,我不知道我是否已经完全探究他们。
所以我在寻找任何类型的最佳实践,现有的算法来处理这种类型的系统,指导选择等
取决于你要提供给用户什么应用语义,你可能会选择不同的解决方案。 例如,如果你实际上是在谈论标记用关键字脱机用户创建的对象,并希望分享跨越不同用户创建多个对象的标签,然后使用“文本”的标签是好的,如你所说。 一旦每个人的更改将被合并,用同样的“文字”标签一样,说:“这是真棒”,将被共享。
还有其他的方法来处理断开更新共享对象。 SVN,CVS和其他版本控制系统自动尝试解决冲突,而当不了,只会让用户有冲突。 你可以这样做,只是告诉用户出现了并发更新和用户必须处理的分辨率。
另外,您也可以登录的更新变化的单位,并且尝试撰写的变化在一起。 例如,如果你的共享对象是一个帆布,和应用程序的语义允许共享同一画布,然后断开连接的更新时绘制一条线从点A至点B上绘制,而另一个断开更新从点C画线到点d,可以由。 在这种情况下,如果你把这两个更新,因为只有两个操作,您可以订购两个更新和重新连接,每个用户上传所有的离线操作和来自其他用户的应用缺少操作。 你可能需要某种形式的排序规则,也许是基于版本号。
另一种选择:如果更新共享对象不能自动协调,并且应用程序的语义不支持通知用户,并要求用户解决因断开的更新冲突,那么你也可以使用版本树来处理这个问题。 每次更新共享对象创建一个新的版本,与过去的版本为母体。 当有来自两个不同的用户断开连接的更新的共享对象中,两个独立的儿童版本/叶节点从相同的父版本引起的。 如果状态的应用程序的内部表示这个版本的树,那么你的应用程序的内部状态保持,尽管断开的更新保持一致,并且可以处理版本树的两个分支在一些其他的方式(例如让分支的用户知道并为他们创造工具合并分支,如在源控制系统)。
就在几个选项。 希望这可以帮助。
作为一个完全从左外野的建议,我想知道,如果使用类似CouchDB的可能适用于您的情况。 它的复制功能可以处理大量的在线/离线同步问题对你来说,包括机制,允许应用程序来处理解决冲突的时候发生。
你的问题是非常相似的版本系统,如SVN。 你可以采取从这些例子。
每个用户都将有一组个人对象加,他们需要的任何共享对象。 在当地,就好像他们所拥有的所有对象,他们将工作。
在同步,客户端将首先下载中的对象的任何变化,并自动同步的内容是显而易见的。 在你的榜样,如果有来自具有相同名称的服务器端传来的一个新的标签,那么它会相应地更新本地系统上的UUID。
这也将是一个不错的地方,在其中检测和处理像从另一个客户端提交的数据的情况下,但同一用户。
一旦客户有数据的更新和合并版本,你可以做一个上传。
这里将是往返的,但我看不出这样做没有过于复杂的数据结构,并具有在你做同步的方式潜在缺陷的方法。