我该怎么做才能防止在wiki风格的网站上发生写写冲突?

时间:2009-03-08 19:54:19

标签: usability wiki

在wiki风格的网站上,我还能做些什么来阻止或减轻write-write conflicts,同时仍允许网站快速运行并保持网站易于使用?

我预见到的问题是:

  1. 用户A开始编辑文件
  2. 用户B开始编辑文件
  3. 用户A完成编辑文件
  4. 用户B完成编辑文件,意外覆盖用户A的所有编辑
  5. 以下是我提出的一些方法:

    • 有一些结账/登记/锁定系统(虽然我不知道如何阻止人们将文件保存“太久”,我不希望用户感到沮丧不允许进行编辑)
    • 有某种diff系统显示当用户提交更改并允许某种合并时所做的其他更改(但我担心这很难创建并会使网站“太难” “使用”
    • 在他们进行更改时(某种AJAX?)通知用户并发编辑

    还有其他方法吗?任何实现这个的网站的例子都可以吗?

8 个答案:

答案 0 :(得分:17)

记住上次更改的版本号(或ID)。然后在写入之前阅读该条目,并比较该版本是否仍然相同。

如果发生冲突,请通知正在尝试编写同时更改的条目的用户。用差异支持他。

大多数维基都是这样做的。 MediaWikiUsemodetc

答案 1 :(得分:5)

三向合并:首先要指出的是,大多数并发编辑,特别是在较长文档上,都是针对文本的不同部分。因此,通过注意用户A和B获得的修订,我们可以进行三向合并,详见Bill Ritcher of Guiffy Software。三向合并可以识别从原始文件进行编辑的位置,除非它们发生冲突,否则它可以将两个编辑内容静默地合并到一篇新文章中。理想情况下,此时执行合并并向用户B显示新文档,以便她可以选择进一步修改它。

碰撞解决方案: 当两个编辑器编辑同一部分时,这将为您提供方案。在这种情况下,合并其他所有内容并将三个版本的文本提供给用户B - 也就是说,包括原始文本 - 用户A的文本框中的版本或用户B的版本。该选择取决于您是否认为默认值应接受最新(用户只需单击“保存”以保留其版本)或强制编辑器进行两次编辑以获取其更改(他们必须将其更改重新应用于编辑器A的版本的部分)。

使用这样的三向合并可以避免锁定,这在网络上很难处理(你让他们有多长时间锁定?),以及加重“你可能想再看一下”的场景,这只适用于论坛风格的回复。它还保留了网络的后响应风格。

如果你想稍微改进它,可以动态3路将用户A的版本合并到用户B的版本中,同时进行编辑,并通知他们。现在这将是令人印象深刻的。

答案 2 :(得分:4)

在Mediawiki中,服务器接受第一次更改,然后在保存第二次编辑时出现冲突页面,然后第二个人将两个更改合并在一起。见Wikipedia: Help:Edit Conflicts

答案 3 :(得分:1)

使用锁定机制可能是最容易实现的。每篇文章都有一个与之关联的锁定字段和锁定时间。如果锁定时间超过某个设定值,则您认为锁定无效,并在检查文章进行编辑时将其删除。您还可以跟踪打开的锁定并在会话结束时删除它们。您还需要在数据库中实现一些并发控制(可能是自动生成的时间戳),这样您就可以确保检查已签出的版本的更新,以防有两个人能够编辑文章在同一时间。只有具有正确版本的版本才能成功签入编辑。

您也可以找到一个可以用来构建差异的差异引擎,虽然在wiki编辑器中显示它们可能会有问题 - 实际显示差异可能比构建差异更难。您需要依靠版本控制系统来检测何时需要拒绝编辑并执行差异。

答案 4 :(得分:1)

在Gmail中,如果我们正在撰写对邮件的回复而其他人在我们仍在键入时发送回复,则会出现一个弹出窗口,指示有新的更新,并且更新本身显示为另一个没有重新加载页面的帖子。这种方法可以满足您的需求,如果您可以使用Ajax显示确切的帖子,其中包含指向刚刚更新的差异的链接,而用户B仍在忙着输入他的条目,这将非常棒。

答案 5 :(得分:1)

正如Ravi(及其他人)所说,您可以使用AJAX方法,并在进行其他更改时通知用户。提交编辑时,只需指出文本差异,让第二个用户了解如何合并这两个版本。

但是,除了这些之外,我还想添加一些你可以尝试的新内容:在编辑器进行编辑时打开聊天对话框。例如,您可以使用嵌入式Gabbly之类的东西。


我说,最好的冲突解决方案是直接对话。

答案 6 :(得分:0)

使用Optimistic Concurrency Control最好解决您的问题(丢失更新)。

一种实现是在系统的每个可编辑实体中添加版本列。在用户编辑时,您加载行并在用户上显示html表单。隐藏字段给出了版本,假设 3 。更新查询需要看起来像:

update articles set ..., version=4 where id=14 and version=3;

如果返回的行为0,则有人已经更新了第14条。您需要做的就是如何处理这种情况。一些常见的解决方案:

  1. 最后提交获胜
  2. 首次提交胜利
  3. 合并冲突的更新
  4. 让用户决定
  5. 您可以使用时间戳,而不是增加版本 int / long,但不建议使用

      

    从群集环境中检索JVM的当前时间并不一定是安全的,其中节点可能没有时间同步。

    (引自Java Persistence with Hibernate

    hibernate documentation上的更多信息。

答案 7 :(得分:-1)

在我的办公室,我们制定了一项政策,所有数据表都包含4个字段:

  • CreatedBy
  • CreatedDate
  • LastUpdateBy
  • LASTUPDATEDATE

这样就有一个很好的审计线索,关于谁对记录做了什么,至少在最近一次。

但最重要的是,比较屏幕上当前或编辑记录的LastUpdateDate变得容易(要求您将其存储在页面上,cookie中,无论如何,与数据库中的值一起存储。如果值不匹配,你可以决定从那里做什么。