The world's most popular open source database
Una lectura con bloqueo, un UPDATE, o un
DELETE generalmente establecen bloqueos sobre cada
registro de índice que es examinado durante el procesamiento de la
consulta SQL. No importa si en la consulta hay condiciones
WHERE que excluirían la fila, InnoDB no
recuerda exactamente la condición WHERE, solamente
los rangos de índices que fueron examinados. Los bloqueos sobre los
registros son normalmente bloqueos de próxima clave, que también impiden
las inserciones en las posiciones vacías (“gap”)
inmediatamente anteriores a los registros.
Si los bloqueos a establecer son exclusivos, entonces
InnoDB recupera también los registros de índices
agrupados (clustered) y los bloquea.
Si no hay índices apropiados para la consulta y MySQL debe examinar la tabla entera para procesarla, se bloqueará cada fila en la tabla, lo que impide cualquier inserción de otros usuarios. Es importante crear índices adecuados de modo que las consultas no examinen muchas filas innecesariamente.
SELECT ... FROM es una lectura consistente, que
lee una captura de la base de datos y no establece bloqueos a
menos que el nivel de aislamiento de la transacción sea
SERIALIZABLE. Para el nivel
SERIALIZABLE, se establecen bloqueos compartidos
de próxima clave en los registros de índice encontrados.
SELECT ... FROM ... LOCK IN SHARE MODE establece
bloqueos compartidos de próxima clave en todos los registros de
índice hallados por la lectura.
SELECT ... FROM ... FOR UPDATE establece
bloqueos exclusivos de próxima clave en todos los registros de
índice hallados por la lectura.
INSERT INTO ... VALUES (...) establece un bloqueo
exclusivo sobre la fila insertada. Nótese que no se trata de un
bloqueo de próxima clave, y no evita que otros usuarios inserten
registros en la posición vacía precedente. Si ocurriese un error por
duplicación de claves, se establecerá un bloqueo compartido sobre el
registro de índice duplicado.
Mientras se inicializa una columna previamente declarada
AUTO_INCREMENT, InnoDB
establece un bloqueo exclusivo al final del índice asociado con
dicha columna. Al accederse al contador de autoincremento,
InnoDB emplea una modo de bloqueo de tabla
específico llamado AUTO-INC, que dura solamente
hasta el final de la actual consulta SQL, en lugar de existir hasta
el final de la transacción. Consulte Sección 15.10.2, “InnoDB y AUTOCOMMIT”.
En MySQL 5.0, InnoDB trae el valor de una columna
previamente declarada AUTO_INCREMENT sin
establecer ningún bloqueo.
INSERT INTO T SELECT ... FROM S WHERE ...
establece un bloqueo exclusivo (pero no de próxima clave) en cada
fila insertada dentro de T. La búsqueda en
S se hace como una lectura consistente, pero se
establecen bloqueos compartidos de próxima clave en
S si está activado el registro binario (binary
logging) de MySQL. InnoDB tiene que establecer
bloqueos en este último caso: en una recuperación de tipo
roll-forward desde una copia de respaldo, cada semtencia SQL debe
ser ejecutada en exactamente la misma manera en que se hizo
originalmente.
CREATE TABLE ... SELECT ... lleva a cabo el
SELECT como una lectura consistente o con
bloqueos compartidos, como en el punto anterior.
REPLACE se ejecuta del mismo modo que una
inserción si no hay colisiones con claves únicas. En otro caso, se
coloca un bloqueo exclusivo de próxima clave en la fila que será
actualizada.
UPDATE ... WHERE ... establece un bloqueo
exclusivo de próxima clave sobre cada registro encontrado por la
búsqueda.
DELETE FROM ... WHERE ... establece un bloqueo
exclusivo de próxima clave sobre cada registro encontrado por la
búsqueda.
Si se define una restricción FOREIGN KEY sobre
una tabla, cualquier inserción, actualización o eliminación que
necesite la verificación de las condiciones impuestas por la
restricción establecerá bloqueos compartidos a nivel de registro
sobre los registros examinados durante la verificación.
InnoDB también establece estos bloqueos en el
caso de que la verificación falle.
LOCK TABLES establece bloqueos de tabla, pero es
la capa de MySQL de mayor nivel por debajo de la capa de
InnoDB la que establece estos bloqueos.
InnoDB tiene conocimiento de los bloqueos de
tabla si se establecen innodb_table_locks=1 y
AUTOCOMMIT=0, y la capa de MySQL por debajo de
InnoDB sabe acerca de los bloqueos a nivel de
fila. En otro caso, la detección automática de deadlocks de InnoDB
no puede detectar los deadlocks donde estén involucradas estas
tablas. Además, puesto que la capa superior de MySQL no sabe acerca
de bloqueos a nivel de fila, es posible obtener un bloqueo de tabla
sobre una tabla donde otro usuario ha colocado bloqueos a nivel de
fila. Sin embargo, esto no pone en peligro la integridad de la
transacción, como se dice en
Sección 15.10.10, “Detección de interbloqueos (deadlocks) y cancelación de transacciones (rollbacks)”. Consulte también Sección 15.16, “Restricciones de las tablas InnoDB”.
Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.

