防止在通过 PHP 编辑 MySQL 行时同时覆盖


Preventing simultaneous overwrites when editing a MySQL-row through PHP

我不确定如何简洁地问这个问题,所以我将通过情境来解释它。

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

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

这两个用户不知道彼此的意图。

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

用户B对MySQL行进行了微小的更改,并将其保存到数据库中。MySQL 行变为'Cannot touch this. Please avoid contractions.'

由于用户 B 决定在用户 A 完成修改之前修改 MySQL 行,因此用户 A 所做的修改将被用户 B 所做的修改覆盖。

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

最简单的解决方案是向任何可以通过这种方式编辑的表添加至少一个额外的字段。指示该行已锁定的内容。为了增加实用性,您应该记录何时锁定该行以及由谁锁定。

还需要一个定时作业来解锁被放弃的记录,否则有人可以按顺序编辑每条记录,放弃编辑并锁定整个数据库。

类似的事情发生在SO上。如果您正在编辑某人的问题,而其他人在您工作时保存了编辑内容,则会收到一条通知,告知您问题已更改,您的编辑不再有效。

您可以使用行级锁定来强制在序列中(而不是同时)进行编辑。 这通常是您希望在设计一种合并更改的方法时要做的,这会在以后为您省去一些麻烦。

如果您在将提交更改发送到数据库/处理脚本的形式中使用时间戳和健全性变量,这也很有用。 然后,您可以在写入数据库之前将其与数据库进行检查,如果没有;向用户发送一条消息,指出在他/她自己的帖子或更改之前有帖子或更改。并在提交自己的之前让 htem 看到它。

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

我喜欢

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