SQL最后一次插入Drupal。它真的线程安全吗?

时间:2022-09-12 08:39:40

I have a query that might be executed by several users consecutively. I'm scared that if I run the db_last_insert_id command, some users might not get the last insert id, due to concurrency. But according to: http://api.drupal.org/api/function/db_last_insert_id/6, it sates:

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

Returns the last insert id. This function is thread safe.

返回最后一个插入ID。此功能是线程安全的。

My question is, how is this thread safe? The code is only:

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

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

I don't see anything about locking tables or nothing?

我没有看到任何关于锁定表或什么都没有?

1 个解决方案

#1


19  

Using MySQL (as you seem to indicate with the tags on your question), the function db_last_insert_id() is defined this way :

使用MySQL(您似乎用问题上的标记表示),函数db_last_insert_id()以这种方式定义:

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

in database.mysql-common.inc


And LAST_INSERT_ID() depends on the connection (quoting, emphasis mine) :

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

The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.

生成的ID在每个连接的基础上在服务器中维护。这意味着函数返回给定客户端的值是为该客户端影响AUTO_INCREMENT列的最新语句生成的第一个AUTO_INCREMENT值。其他客户端不会影响此值,即使它们生成自己的AUTO_INCREMENT值也是如此。此行为可确保每个客户端都可以检索自己的ID,而无需考虑其他客户端的活动,也无需锁定或事务。

So, I'd say that this is quite OK for MySQL ;-)

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


The definition your posted is actually the one used for PostGreSQL :

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

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

In database.pgsql.inc


From pgsql manual on sequences (quoting ; emphasis mine) :

从序列上的pgsql手册(引用;强调我的):

currval

Return the value most recently obtained by nextval for this sequence in the current session. (An error is reported if nextval has never been called for this sequence in this session.) Notice that because this is returning a session-local value, it gives a predictable answer whether or not other sessions have executed nextval since the current session did.

返回当前会话中此序列的nextval最近获得的值。 (如果在此会话中从未为此序列调用nextval,则会报告错误。)请注意,由于这会返回会话本地值,因此无论其他会话是否已执行nextval,因此它提供了可预测的答案。

So, I'm guessing this is quite OK too, for PostGreSQL.

所以,对于PostGreSQL,我猜这也很好。

#1


19  

Using MySQL (as you seem to indicate with the tags on your question), the function db_last_insert_id() is defined this way :

使用MySQL(您似乎用问题上的标记表示),函数db_last_insert_id()以这种方式定义:

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

in database.mysql-common.inc


And LAST_INSERT_ID() depends on the connection (quoting, emphasis mine) :

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

The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.

生成的ID在每个连接的基础上在服务器中维护。这意味着函数返回给定客户端的值是为该客户端影响AUTO_INCREMENT列的最新语句生成的第一个AUTO_INCREMENT值。其他客户端不会影响此值,即使它们生成自己的AUTO_INCREMENT值也是如此。此行为可确保每个客户端都可以检索自己的ID,而无需考虑其他客户端的活动,也无需锁定或事务。

So, I'd say that this is quite OK for MySQL ;-)

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


The definition your posted is actually the one used for PostGreSQL :

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

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

In database.pgsql.inc


From pgsql manual on sequences (quoting ; emphasis mine) :

从序列上的pgsql手册(引用;强调我的):

currval

Return the value most recently obtained by nextval for this sequence in the current session. (An error is reported if nextval has never been called for this sequence in this session.) Notice that because this is returning a session-local value, it gives a predictable answer whether or not other sessions have executed nextval since the current session did.

返回当前会话中此序列的nextval最近获得的值。 (如果在此会话中从未为此序列调用nextval,则会报告错误。)请注意,由于这会返回会话本地值,因此无论其他会话是否已执行nextval,因此它提供了可预测的答案。

So, I'm guessing this is quite OK too, for PostGreSQL.

所以,对于PostGreSQL,我猜这也很好。