2011-05-11 36 views
14

我不确定如何简洁地问这个问题,所以我会通过情境来解释它。防止在通过PHP编辑MySQL行时同时覆盖

用户A决定他想通过HTML格式修改MySQL行。 同时,用户B决定他也希望以相同的方式修改相同的MySQL行。

我们会说MySQL的行是一个文本字段,它包含文本,'Can\'t touch this'

两个用户没有eachothers意向的知识。

User-A对MySQL行进行重大更改并将其保存到数据库。 MySQL行变为'Can\'t touch this was a popular track by the Hip-Hop artist M.C. Hammer.'

User-B对MySQL行进行小改动并将其保存到数据库。 MySQL行变为'Cannot touch this. Please avoid contractions.'

因为User-B决定在User-A完成其修改之前修改MySQL行,所以修改用户-A因User-B所做的修改而被覆盖。

如何允许同时编辑数据库行的脚本(如MediaWiki或任何其他维基软件)处理此问题?

+0

AFAIK mediawiki不允许同时编辑其文档。上次我检查他们表明是否有人正在编辑文档,并告诉你避免在此期间进行更改。 – Gal 2011-05-11 19:46:29

+0

几周前,SO允许同时进行编辑,直接覆盖以前的编辑,恕不另行通知。目前,该网站发布了一条错误消息,表明其他人编辑了帖子(或提出了编辑),从而不允许我(暂时)保存编辑的消息,让我浪费时间和精力进行无用的编辑。顺便说一句,我想你在倒数第二段中交换了结果。 – 2011-05-11 20:00:14

+0

@sombe这是我以前使用的方法。然而,我发现了一个缺陷,因为锁定时间过长,用户合法地进行长时间编辑会超过然后无法提交,因为它变得自由并被其他人锁定。 – Kairu 2011-05-12 02:39:19

回答

5

最简单的解决方法是在可以用这种方式编辑的任何表中添加至少一个额外的字段。指示行被锁定的东西。为了增加实用性,您应该记录该行何时被锁定以及由谁进行。

解锁已放弃记录的定时作业也是需要的,否则有人可能只是依次编辑每条记录,放弃编辑并锁定整个数据库。

在这里发生了类似的事情。如果您正在修改某人的问题,而其他人在您离开时保存了修改内容,则会发现该问题已更改,您的修改不再有效。

+1

虽然时间锁定还有一个缺点。在合理的情况下,有人可能会做出巨大的修改,可能需要超出锁定期限的时间。 – Kairu 2011-05-12 02:32:52

+0

确实如此,但您可以使用ajax心跳来刷新锁定。 – 2011-05-12 04:12:59

+0

真的!我可能会走这条路。就像我在脚本中使用Ajax一样,它确实有它的用处。现在,只需要弄清楚如何做到这一点! – Kairu 2011-05-14 18:38:35

4

您可以使用行级锁定来强制编辑在系列中完成(而不是同时)。这通常是您想要设计合并更改的方法,稍后可以为您节省一些麻烦。

如果在将提交更改发送到数据库/处理脚本的表单中使用时间戳和完整性变量,它也会有所帮助。然后你可以在写入数据库之前检查它,如果没有,给用户一条消息,告诉他们在他/她自己之前有帖子或者变化。让他们在提交他们自己的消息之前看到它。

+0

行级锁定无法在基于Web的情况下工作,因为当前请求完成时db连接通常会被切断。该锁将在请求期间保持不变,然后释放并保持解锁状态,直到下一个请求。同时,其他用户可以进入并编辑相同的记录。 – 2011-05-11 20:01:10

1

我喜欢Wesley Murch方法。 您也可以允许多个用户更改同一文档,并在第二次提交完成时使用合并。编辑前您需要保留原始文档。

+0

合并修订听起来非常密集。虽然,如果我甚至知道从哪里开始,我肯定会尝试。 – Kairu 2011-05-12 02:41:31

3

我知道的最简单的方法之一是向表中添加版本字段。当您读取记录时,您会获取版本字段并将其作为隐藏字段添加到您的编辑表单中。在编辑后回发数据时,您可以获取记录并检查数据库中的版本字段是否仍与您的表单匹配。如果不是,那么该记录在此期间由其他人编辑(您如何处理这个取决于您)。如果匹配,则更改数据并增加版本号。换句话说,乐观锁定的基本实现...

+0

嗯,我没有版本号;而是将所有修订都存储在一个单独的表中,其中的时间字段既是修改时间的添加时间,也是实际页面上次修改时间的时间字段。我正在考虑将该值作为隐藏形式字段传递,并在提交表单时验证它是否与其数据库值匹配。 – Kairu 2011-05-12 02:37:01

+1

这确实相当于相同的功能。您还可以通过简单的方法来检查在此期间是否有更改(如果时间戳不匹配)。 – wimvds 2011-05-12 07:11:47