【问题标题】:Do I need to lock a MySQL table when doing a SELECT followed by an INSERT?在执行 SELECT 后执行 INSERT 时是否需要锁定 MySQL 表?
【发布时间】:2011-08-25 02:07:31
【问题描述】:

我不是数据库专家,所以我很好奇在以下情况下是否需要表锁:

  • 我们有一个网络应用程序,允许用户通过 HTML 表单向数据库添加条目
  • 用户添加的每个条目都必须有一个唯一的 URL
  • 应该通过从数据库中提取最新的 ID、添加一个并将其附加到新创建的条目来动态生成 URL
  • 该应用在 ExpressionEngine 上运行(我仅提及这一点,以防熟悉 EE 平台的人更容易理解我的情况)

相关数据库列 (exp_channel_titles)

  • entry_id(主键,自动增量)
  • url_title(必须是唯一的)

我的假设解决方案——这里需要表锁定吗?

假设表中有100个条目,表中的每个条目都有一个url_title,如entry_1、entry_2、entry_3等,一直到entry_100。每次用户添加条目时,我的脚本都会执行以下操作:

  1. 查询 (SELECT) 表以确定最后一个 entry_id 并将其分配给变量 $last_id
  2. 将返回值加 1,并将总和赋给变量 $new_id
  3. 插入新条目,将最新条目的 url_title 字段设置为 entry_$new_id(因此表中的第 101 个条目的 url_title 为 entry_101)

由于我的数据库知识有限,不知道这里是否需要担心锁定问题。如果一千个人试图在 10 秒内向数据库添加条目会怎样? MySQL 会自动处理这个问题,还是我需要在添加每个新条目时锁定表,以确保每个条目都有正确的 id?

在 MyISAM 引擎上运行,如果有影响的话。

【问题讨论】:

    标签: mysql locking expressionengine


    【解决方案1】:

    我认为你应该看看以下两种方法之一:

    • 使用和AUTO_INCREMENT 列分配id
    • 从 MyISAM 切换到完全事务性的 InnoDb 存储引擎,并将您的查询包装在事务中

    【讨论】:

    • @James C,感谢您的回复。 ID 已经是一个自动递增字段。我们都在说同一个专栏吗?对于您的第二个建议,我不知道这是一种可能性。我正在使用 ExpressionEngine,它默认使用 MyISAM 引擎。如果可以切换,“完全事务性”是什么意思,我将如何将我的查询包装在事务中?
    猜你喜欢
    • 2010-09-24
    • 2011-12-12
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 2019-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多