我的查询可能会被多个用户连续执行。我很害怕,如果我运行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')"));
}
?>
我没有看到关于锁定表或什么都没有看到的内容?
答案 0 :(得分:19)
使用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从来没有报道过 在这里要求这个序列 会议。)请注意,因为这是 返回会话本地值,它 无论是否给出可预测的答案 没有其他会话执行 自当前会议开始以来。
所以,我猜这对PostGreSQL来说也是可以的。