vulnerability seccion race ejemplo critica condicion carrera php mysql sql transactions lastinsertid

php - seccion - Condiciones de carrera con mysql_last_id()



race condition vulnerability (2)

La ejecución del script php es lineal, no multihilo.
Entonces, es imposible tener una condición cuando un objeto se ejecuta al mismo tiempo con otro

El único problema posible puede ser con la conexión persistente . Pero parece que la misma conexión no puede ser utilizada por 2 llamadas separadas de todos modos. Incluso si es persistente, si ya está en uso, no puede ser utilizado por otro script. Por lo tanto, no habrá problemas tampoco.

Pasé la mayor parte del día tratando de encontrar una respuesta a esto, pero parece que no hay uno por ahí. Necesito una función que crea una fila en una tabla, recupera el autoincremento de la fila insertada y luego usa ese valor para insertar otra fila en una segunda tabla. Algo funcionalmente similar al siguiente php:

$mysql_query("INSERT INTO table1 SET columns=''values''"); $id = mysql_insert_id(); $mysql_query("INSERT INTO table2 SET id=''$id'', columns=''values''");

El problema al que me estoy enfrentando es que en mi aplicación, una sola conexión MySQL es compartida entre todas las clases, así que me preocupa que esto pueda causar una condición de carrera en la que otra clase inserte una fila entre la primera y la segunda línea. de los anteriores.

La solución más simple que se me ocurre es tener cualquier función que use mysql_insert_id() abrir una conexión nueva y única, pero eso parece una gran cantidad de sobrecarga innecesaria. Otras respuestas con las que jugué incluyen insertar un valor único (posiblemente creado con UUID() ) y usarlo en lugar de un valor de incremento automático, o posiblemente colocar el primer inserto y una llamada a LAST_INSERT_ID() en una función almacenada ( aunque no estoy seguro si eso resolvería la posible condición de carrera o no).

También he estado investigando las transacciones para ver si pueden ayudar, pero hay poca documentación sobre cómo exactamente mysql_insert_id() interactúa con ellos. Lo mejor que puedo decir es que probablemente no ayuden aquí, ya que otro INSERT que no entró en conflicto con alguna de las bloqueos de la transacción todavía podría ejecutarse y posiblemente causaría la misma condición de carrera.

Entonces, asumiendo que no estoy equivocado con ninguno de los anteriores (y por favor corrígeme si lo estoy), ¿cuál es la mejor manera de garantizar al 100% que el segundo INSERT usa el valor adecuado?


Intenta usar si es condicional

ejemplo

if(mysql_query(query)){ $id = mysql_last_id(); mysql_query(query using $id); }