Pregunta

¿Esto causa una condición de carrera con MySQL (InnoDB):

  1. iniciar la transacción.

  2. Trate de obtener el registro.

  3. Si no existe registro, cambio.

  4. Si existe registro, suprimirlo y añadir una entrada de registro diciendo que se ha sido eliminada.

  5. Fin de transacción (commit / rollback).

¿Es posible que otro proceso para comenzar justo antes de la etapa de eliminación en 2b, detectar la presencia de un disco y luego tener ambos procesos entran elemento eliminar entradas en el registro?

¿Hay algunas precauciones que tengo que tomar?

Gracias.

¿Fue útil?

Solución

será capaz de obtener un bloqueo en la fila evitando así el escenario que usted describe

Utilice 'seleccione para la actualización' en el paso 2. Sólo un proceso.

Otros consejos

Viajero en el programador, creo, tiene la solución correcta. Puesto que usted ha indicado que está utilizando una herramienta ORM roto (uno que no permita realizar consultas para la actualización) yo sugeriría que se mueve el INSERT en la tabla de registro en un gatillo de la operación de eliminación por lo que evitar el duplicado entrada.

iniciar la transacción.

Eliminar registro / * utilizando los mismos criterios que utiliza para 'tratar de obtener el registro' * /

si la respuesta indica récord fue de hecho eliminada, agregar una entrada de registro.

Fin de transacción (commit / rollback).

No más condición de carrera.

Sí, es posible que otra transacción para comprobar la mesa después de haberlo leído.

Peor aún, debido a cómo funcionan las transacciones, incluso después de que se elimina la fila, las nuevas operaciones que se inician verán la fila porque todavía no se ha comprometido la eliminación.

SELECT ... FOR UPDATE es una manera de evitarlo.

LOCK TABLE tablename es otro.

Por desgracia, ya que usted está usando un ORM, no podría decir si tiene la capacidad de hacer cualquiera de estos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top