2012-09-26 28 views
5

Estoy utilizando el bloqueo de filas (transacciones) en MySQL para crear una cola de trabajos. El motor utilizado es InnoDB.Desventajas de MySQL Row Locking

consultas SQL

START TRANSACTION; 
SELECT * 
FROM mytable 
WHERE status IS NULL 
ORDER BY timestamp DESC LIMIT 1 
FOR UPDATE; 
UPDATE mytable SET status = 1; 
COMMIT; 

De acuerdo con esta webpage,

The problem with SELECT FOR UPDATE is that it usually creates a single synchronization point for all of the worker processes, and you see a lot of processes waiting for the locks to be released with COMMIT.

Pregunta: ¿Quiere decir esto que cuando se ejecuta la primera consulta, que toma un tiempo para terminar th e transacción anterior, cuando se produce la segunda consulta similar antes de que se haya comprometido la primera transacción, tendrá que esperar a que finalice antes de que se ejecute la consulta. Si esto es cierto, entonces no entiendo por qué el bloqueo de fila de una sola fila (que supongo) afectará a la próxima consulta de transacción que no requeriría leer esa fila bloqueada?

Además, ¿se puede resolver este problema (y aún así lograr el efecto de bloqueo de fila para una cola de trabajos) haciendo un UPDATE en lugar de la transacción?

UPDATE mytable SET status = 1 
WHERE status IS NULL 
ORDER BY timestamp DESC 
LIMIT 1 
+0

El bloqueo se basa en el motor de almacenamiento, ¿qué estás usando? –

+0

Editado el post, es InnoDB – Nyxynyx

+0

Gracias (y 9 caracteres más para ir) –

Respuesta

1

Si utiliza PARA UPDATE con un motor de almacenamiento que utiliza páginas o registros cerraduras, registros examinados por la consulta son escritura bloqueado hasta el final de la transacción actual. El uso de LOCK IN SHARE MODE establece un bloqueo compartido que permite que otras transacciones lean las filas examinadas pero no las update or delete. y sobre esta consulta

UPDATE mytable SET status = 1 
WHERE status IS NULL 
ORDER BY timestamp DESC 
LIMIT 1 

desde INNODB

adquirir automáticamente bloqueos durante el procesamiento de instrucciones SQL creo que funciona como el mismo.