2009-09-11 10 views
8

Tengo una consulta que puede ser ejecutada por varios usuarios consecutivamente. Tengo miedo de que si ejecuto el comando db_last_insert_id, algunos usuarios no obtengan la última identificación de inserción, debido a la concurrencia. Pero de acuerdo con: http://api.drupal.org/api/function/db_last_insert_id/6, sates:Última inserción de SQL en Drupal. ¿Es realmente inseguro?

Devuelve la última identificación de inserción. Esta función es segura para subprocesos.

Mi pregunta es, ¿cómo es seguro este subproceso? El código es solamente:

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

No veo nada acerca de bloquear mesas o nada?

Respuesta

19

Usar MySQL (como parece indicar con las etiquetas en su pregunta), la función db_last_insert_id() se define de esta manera:

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

en database.mysql-common.inc


Y LAST_INSERT_ID() depende de la conexión (citando, énfasis mío):

El ID que se ha generado se mantiene en el servidor en un base por conexión. Esto significa que el valor devuelto por la función a un cliente determinado es el primer valor AUTO_INCREMENT generado para la declaración más reciente que afecta a una columna AUTO_INCREMENT de ese cliente. Este valor no puede ser afectado por otros clientes, incluso si generan AUTO_INCREMENT valores de su propia. Este comportamiento se asegura de que cada cliente puede recuperar su propio ID y sin preocupación por la actividad de otros clientes , y sin la necesidad de cerraduras o transacciones.

Por lo tanto, yo diría que esto está bastante bien para MySQL ;-)


La definición de su publicado en realidad es la que se utiliza para PostgreSQL:

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

En database.pgsql.inc


De pgsql manual on sequences(citando; énfasis mi ne):

currval

Devuelve el valor más recientemente obtiene nextval para esta secuencia en la sesión actual.(Un error se informó si nextval nunca ha sido llamada para esta secuencia en esta sesión .) Tenga en cuenta que debido a esto es devolver un valor de sesión local, que da una respuesta predecible, ya sea o no otras sesiones han ejecutado nextval ya que la sesión actual hizo.

Entonces, supongo que esto también es bastante bueno para PostGreSQL.

+1

Gracias. Ojalá pudiera darte diez UPS. – coderama

+2

De nada :-) huhu ^^ tendrá que hacer otras 10 preguntas, de las cuales sé la respuesta :-D –

Cuestiones relacionadas