【问题标题】:SQL last insert in Drupal. Is it really threadsafe?SQL 最后一次插入 Drupal。它真的是线程安全的吗?
【发布时间】:2009-09-11 10:51:15
【问题描述】:

我有一个可能由多个用户连续执行的查询。我担心如果我运行 db_last_insert_id 命令,由于并发性,某些用户可能无法获得最后一个插入 ID。但是根据:http://api.drupal.org/api/function/db_last_insert_id/6,它是:

返回最后一个插入 id。这个函数是线程安全的。

我的问题是,这个线程如何安全?代码只有:

<?php
  function db_last_insert_id($table, $field) {
   return db_result(db_query("SELECT CURRVAL('{". db_escape_table($table) ."}_". db_escape_table($field) ."_seq')"));
  }
?> 

我没有看到任何关于锁定表的信息或什么也没有?

【问题讨论】:

    标签: mysql drupal concurrency multithreading


    【解决方案1】:

    使用 MySQL (正如您在问题上的标签所示),函数 db_last_insert_id() 是这样定义的:

    function db_last_insert_id($table, $field) {
      return db_result(db_query('SELECT LAST_INSERT_ID()'));
    }
    

    在database.mysql-common.inc


    而LAST_INSERT_ID() 取决于连接(引用,强调我的):

    生成的 ID 是 维护在服务器上 每个连接的基础。这意味着 函数返回的值 给定的客户是第一个 AUTO_INCREMENT 生成的值 影响一个最近的声明 该客户端的 AUTO_INCREMENT 列。 此值不受其他影响 客户,即使他们生成 AUTO_INCREMENT 自己的值。 此行为可确保每个客户端 可以检索自己的 ID 而无需 关心他人的活动 客户,而无需 锁或事务。

    所以,我会说这对 MySQL 来说还不错 ;-)


    您发布的定义实际上是用于 PostGreSQL 的定义:

    function db_last_insert_id($table, $field) {
      return db_result(db_query("SELECT CURRVAL('{". db_escape_table($table) ."}_". db_escape_table($field) ."_seq')"));
    }
    

    在database.pgsql.inc


    来自pgsql manual on sequences(引用;强调我的):

    currval

    返回最近的值 由 nextval 为这个序列获得 在当前会话中。 (错误是 如果 nextval 从未被报告过 在这个中要求这个序列 会话。)请注意,因为这是 返回一个会话本地值,它 给出一个可预测的答案 未执行其他会话 自当前会话以来的 nextval 。

    所以,我猜这对于 PostGreSQL 来说也没什么问题。

    【讨论】:

    • 谢谢。我希望我能给你十个 UPS。
    • 不客气 :-) huhu ^^ 你还得问其他 10 个问题,我知道答案 :-D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多