我应该使用MySQL的自定义'锁'表吗?

时间:2011-06-12 10:26:51

标签: mysql concurrency locking locks

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

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

  • 正如我所说,我正在使用MyISAM,据我所知,它不支持行级锁。此外,我不确定是否建议将“真正的”MySQL锁保持几分钟。
  • 我对交易并不是很了解,但从我所看到的情况来看,它们似乎意味着要在一个连接中使用。
  • 使用像Git这样的某种冲突合并系统确实不是一种选择。

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

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

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

2 个答案:

答案 0 :(得分:3)

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

这个问题的一个难点是当有人编辑但未能在锁定间隔内提交时该怎么办。 所以:

  1. lock_interval是2分钟。
  2. 在0:00时,Alice会锁定页面,编辑内容,但会接到电话而不提交更改
  3. 在时间2:30,Bob检查页面,获取编辑锁定,因为Alice的锁定已过期,并进行了编辑
  4. 在3:00时,Alice回到她的comp,按提交 - >冲突。
  5. 有人未提交他们的数据。如果您将锁定设置为过期,则无法解决此问题。 (如果你不这样做,锁可以永远留下。) 您只能决定哪一个优先(使用Bob创建的新锁可能最简单)并通知另一个页面已过期并且数据不会被汇总,并将它们的编辑交给他们重做。

    关于表结构的注释:您可以使用字段'table_name,row_id,lock_created,locked_by'创建表'locks',但它可能不是最简单的方法,因为加入变量表名称很复杂且令人困惑。此外,可能没有用于存储所有锁的单个位置。对于一个简单的机制,我认为在你想要实现锁定机制的每个表中添加统一字段更容易。

答案 1 :(得分:0)

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

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