2011-06-12 64 views
1

我正在开发一个相对简单的自定义Web应用程序,并在后端安装了MySQL MyISAM数据库。不知何故,我想避免经典的并发覆盖问题,例如该用户A覆盖用户B的编辑,因为B在A完成之前加载并提交了一些编辑表单。我应该使用MySQL的自定义'锁'表吗?

这就是为什么我想以某种方式锁定显示编辑表单的行。然而...

  • 正如我所说,我使用的MyISAM,据我所知,它不支持行级锁。另外,我不确定是否持有“真正的”MySQL锁定几分钟是建议的做法。
  • 我对交易并不十分了解,但从我所看到的看来,它们看起来像是在一个连接中使用。
  • 使用像Git这样的冲突合并系统真的不是一个选项。

行将保持锁定几分钟。并发性非常低:有六位用户随时使用该应用程序。

我现在正在计划使用一张表,详细介绍哪些用户正在做什么以及从何时开始。当其他用户最近打开它时(例如正在处理它),应用程序可以决定不显示编辑表单。在保存表格时,这个假锁将被删除。

会这样吗?我应该怎么做才能避免死锁,活锁和所有这些东西?

回答

3

您可以实现一个锁,最简单的可能是将两个字段添加到要锁定的数据(lock_created Datetime,locked_by int)。然后在编辑页面(也可能在编辑按钮上),你现在检查(lock_created + lock_interval)<() - 如果没有,数据被锁定进行编辑,应该通知用户。 (请注意,您始终需要在编辑页面上进行检查,而不仅仅是编辑按钮。) 同样在提交页面上,您需要检查用户是否仍然有要提交的锁定。 (见下面)

这个难题之一是当有人编辑但在锁定间隔内未能提交时该怎么做。 So:

  1. lock_interval是2分钟。
  2. 在时间0:00 Alice锁定页面,编辑某些内容,但接到电话并且未提交她的更改
  3. 在时间2:30 Bob检查页面,获取编辑锁,因为Alice的锁已过期,并编辑
  4. 在3点时,爱丽丝回到她的比赛,按提交 - >冲突。

有人没有提交他们的数据。如果将锁设置为过期,则无法解决此问题。 (如果你不这样做,锁可以永远留下。) 您只能决定优先考虑哪一个(使用由Bob创建的新锁可能是最简单的),并通知对方页面已过期,数据将不被合并,并将它们的编辑交给他们以重做它们。

关于表结构的说明:您可以创建一个表'locks',其中包含字段'table_name,row_id,lock_created,locked_by',但它可能不是最简单的方法,因为加入变量表名是复杂的混乱。此外,有可能没有用于存储所有锁的单个地方。对于一个简单的机制,我认为为每个要实现锁定机制的表添加统一字段更容易。

+0

感谢您的明确答案!我想我会用相当短的到期时间,并用AJAX以某种方式刷新它们。 – 2011-06-13 07:17:59

0

在这种情况下,您绝对不应该使用行级锁。

您可以使用乐观锁定,这基本上意味着每个行都有一个版本字段,当行被保存时,版本字段会增加。在保存之前,请确保版本字段与加载该行时的版本字段相同,这意味着自从您读取该行后没有其他人保存任何内容。

+0

但是,你会怎样处理'最新'版本,即否则会覆盖'半新'版本?如果此行由其他人编辑,那么失败将意味着用户的某个更改会丢失。 – 2011-06-12 12:06:40

相关问题