2010-05-11 23 views
5

Considere esta situación:¿Una transacción detiene todos los problemas de condición de carrera en MySQL?

  1. iniciar la transacción
  2. inserto 20 registros en una tabla con un AUTO_INCREMENT clave
  3. Obtener el id primera inserción (digamos que es 153)
  4. actualización de todos los registros en esa tabla donde id >= 153
  5. Commit

¿Es seguro el paso 4?

Es decir, si otra solicitud entra casi al mismo tiempo e inserta otros 20 registros después del paso 2 anterior, pero antes del paso 4, ¿habrá una condición de carrera?

+0

¿Por qué tendría usted un paso de actualización por separado en lugar de solo insertar los datos correctos en primer lugar? Eso es bastante extraño. No debería preocuparse por una "condición de carrera" si insertó los datos correctos en primer lugar. Actualizar 'WHERE id> 153' también es una consulta muy extraña. Los identificadores de incremento automático no tienen lógica para ellos, por lo que nunca (hasta donde yo sé) se actualicen únicamente en función de la identificación. Y, por último, no conozco ninguna función de "primera identificación de inserción". –

+0

@ButtleButkus http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id "Si inserta varias filas con una sola instrucción INSERT, LAST_INSERT_ID() devuelve el valor generado para la primera fila insertada " – nickf

+0

Tiene razón acerca de LAST_INSERT_ID(), pero no cambia el hecho de que la pregunta parece tratarse de una situación hipotética que nunca existiría si se siguen la estructura y el procedimiento básicos de la base de datos. ¿Por qué su criterio de actualización alguna vez sería el valor de una identificación sin sentido? No puedo pensar en ninguna razón. No lo llamaría una 'condición de carrera' porque no tiene sentido. ¿Por qué actualizaría inmediatamente después de insertar, cuando podría simplemente insertar los valores correctos para comenzar?Esos son los verdaderos motivos por los que esta pregunta no tiene sentido. –

Respuesta

5

Es decir, si otra solicitud entra casi al mismo tiempo e inserta otros 20 registros después del paso 2 anterior, pero antes del paso 4, ¿habrá una condición de carrera?

Sí, lo hará.

Los registros 21 a 40 se bloquearán con la transacción 2.

La transacción 1 se bloqueará y esperar hasta que la transacción 2 confirme o retrotraiga.

Si la transacción se compromete 2, entonces la transacción se actualizará 140 registros (incluidos los insertado por transacción 2)

+1

¿Puedes aclarar? ¿Estás diciendo que hay un problema o no? – nickf

+0

@nickf: mira la actualización de la publicación. – Quassnoi

0

No creo que esto puede ser catalogada como una condición de carrera, sino más bien como un comportamiento específico DBMS. Básicamente, si el DBMS bloquea los registros recién insertados, entonces la primera transacción no verá los registros de la segunda hasta que se haya confirmado la segunda transacción.

Y, por supuesto, está la cuestión de bloquear la tabla, si la primera transacción escribe-bloquea la tabla y la segunda quedará bloqueada en las escrituras hasta que la primera se complete. Aunque no estoy seguro si el estándar mysql ofrece este tipo de característica. Sé que el servidor MSSQL lo hace.

Cuestiones relacionadas