9

在 wiki 风格的网站上,我可以做些什么来防止或减轻写-写冲突,同时仍然允许网站快速运行并保持网站易于使用?

我预见的问题是这样的:

  1. 用户 A 开始编辑文件
  2. 用户 B 开始编辑文件
  3. 用户 A 完成文件编辑
  4. 用户 B 完成文件编辑,不小心覆盖了用户 A 的所有编辑

以下是我想出的一些方法:

  • 有某种签出/签入/锁定系统(尽管我不知道如何防止人们将文件签出“太长时间”,而且我不希望用户因不被允许而感到沮丧进行编辑)
  • 有某种差异系统,显示用户提交更改并允许某种合并时所做的其他更改(但我担心这将难以创建并且会使网站“太难”使用)
  • 在用户进行更改时通知用户并发编辑(某种 AJAX?)

还有其他方法可以解决这个问题吗?有没有很好地实现这一点的网站示例?

4

8 回答 8

17

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

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

大多数 wiki 都是这样做的。MediaWikiUsemod_ _

于 2009-03-08T20:04:57.563 回答
5

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

冲突解决: 当两个编辑器都编辑了同一部分时,这会给您留下场景。在这种情况下,合并其他所有内容并将三个版本的文本提供给用户 B - 即包括原始文本 - 文本框中包含用户 A 的版本或用户 B 的版本。该选择取决于您是否认为默认应该是接受最新的(用户只需单击保存以保留他们的版本)或强制编辑器编辑两次以获取他们的更改(他们必须将更改重新应用到编辑器 A该部分的版本)。

使用像这样的三向合并避免了锁定,这在网络上很难很好地处理(你让他们锁定多长时间?),以及加重“你可能想再看一次”的情况,这只会适用于论坛式回复。它还保留了 web 的 post-response 风格。

如果您想对其进行 Ajax 处理,请在用户 A 的版本正在编辑时将其动态 3 路合并到用户 B 的版本中,并通知他们。现在那将是令人印象深刻的。

于 2009-03-11T11:30:04.827 回答
4

在 Mediawiki 中,服务器接受第一个更改,然后在保存第二个编辑时出现冲突页面,然后第二个人将两个更改合并在一起。参见维基百科:帮助:编辑冲突

于 2009-03-09T03:10:14.217 回答
1

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

您可能还可以找到一个差异引擎,您可以使用它来构建差异,尽管在 wiki 编辑器中显示它们可能会出现问题——实际上显示差异可能比构建差异更难。您将依靠版本控制系统来检测何时需要拒绝编辑并执行差异。

于 2009-03-08T20:07:06.090 回答
1

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

于 2009-03-15T15:59:19.043 回答
1

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

但是,我想添加一些新的东西,你可以尝试除此之外:在编辑进行编辑时打开他们之间的聊天对话框。例如,您可以为此使用嵌入式Gabbly 之类的东西。
 
 
我说,最好的冲突解决方案是直接对话。

于 2009-03-15T22:12:50.080 回答
0

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

一种实现是在系统的每个可编辑实体中添加一个版本列。在用户编辑时,您加载行并在用户身上显示 html 表单。一个隐藏字段给出了版本,比如说3。更新查询需要类似于:

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

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

  1. 最后一次提交获胜
  2. 第一次提交获胜
  3. 合并有冲突的更新
  4. 让用户决定

您可以使用时间戳而不是递增版本int/long,但不建议这样做,因为:

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

(引用Java Persistence with Hibernate

hibernate 文档中的更多信息。

于 2009-03-12T20:38:29.730 回答
-1

在我的办公室,我们的政策是所有数据表都包含 4 个字段:

  • 由...制作
  • 创建日期
  • 最后更新者
  • 上次更新日期

这样就可以很好地跟踪谁对记录做了什么,至少最近是这样。

但最重要的是,将屏幕上当前或已编辑记录的 LastUpdateDate 与数据库中的值进行比较变得非常容易(需要您将其存储在页面上、cookie 中等)与数据库中的值。如果值不比赛,你可以从那里决定做什么。

于 2009-03-17T22:12:09.670 回答