【问题标题】:Should I use a custom 'locks' table with MySQL?我应该在 MySQL 中使用自定义的“锁”表吗?
【发布时间】:2011-06-12 10:26:50
【问题描述】:

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

这就是为什么我想在显示编辑表单时以某种方式锁定一行。不过……

  • 正如我所说,我使用的是 MyISAM,据我所知,它不支持行级锁。另外,我不确定是否建议将“真正的”MySQL 锁保持几分钟。
  • 我对事务了解不多,但据我所见,它们似乎打算在一个连接中使用。
  • 使用像 Git 这样的某种冲突合并系统确实不是一种选择。

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

我现在正计划使用一个表格,其中包含有关用户在做什么以及从何时开始的详细信息。然后,该应用程序可以决定在其他用户最近打开它时不显示编辑表单(例如正在处理它)。这个假锁将在保存表单时被删除。

这行得通吗?我应该怎么做才能避免死锁、活锁和所有这些东西?

【问题讨论】:

    标签: mysql concurrency locking locks


    【解决方案1】:

    你可以实现一个锁,最简单的可能是向你想要锁定的数据添加两个字段(lock_created Datetime,locked_by int)。然后在编辑页面上(也可能在编辑按钮上)检查 (lock_created + lock_interval)

    其中一个困难的部分是当有人编辑但未能在锁定间隔内提交时该怎么办。 所以:

    1. lock_interval 为 2 分钟。
    2. 在 0:00 时,Alice 锁定了页面,编辑了一些内容,但接到了一个电话并且没有提交她的更改
    3. 在 2:30 时,Bob 检查了页面,因为 Alice 的锁已过期而获得了编辑锁,然后进行了编辑
    4. 在 3:00 时,Alice 回到她的比赛中,按下提交 -> 冲突。

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

    关于表结构的注意事项:您可以使用字段“table_name、row_id、lock_created、locked_by”创建一个表“locks”,但这可能不是最简单的方法,因为连接变量表名很复杂且令人困惑.此外,可能没有任何用处来存储所有锁。对于一个简单的机制,我认为向要实现锁定机制的每个表添加统一字段更容易。

    【讨论】:

    • 感谢您的明确答复!我想我会使用相当短的过期时间并使用 AJAX 以某种方式刷新它们。
    【解决方案2】:

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

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

    【讨论】:

    • 但是你会如何处理“最新”版本,即否则会覆盖“半新”版本的版本?如果在此期间其他人编辑了该行,则失败将意味着用户的其中一项更改丢失。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多