Buscar..


Sintaxis

  • LOCK TABLES table_name [LEER | ESCRIBIR]; // Bloquear tabla

  • TABLAS DE DESBLOQUEO; // Desbloquear Tablas

Observaciones

El bloqueo se utiliza para resolver problemas de concurrencia. El bloqueo se requiere solo cuando se ejecuta una transacción, que primero lee un valor de una base de datos y luego escribe ese valor en la base de datos. Los bloqueos nunca son necesarios para las operaciones de inserción, actualización o eliminación autónomas.

Hay dos tipos de cerraduras disponibles

READ LOCK - cuando un usuario solo lee de una tabla.

ESCRIBIR BLOQUEO: cuando un usuario está leyendo y escribiendo en una tabla.

Cuando un usuario tiene un WRITE LOCK en una tabla, ningún otro usuario puede leer o escribir en esa tabla. Cuando un usuario mantiene un READ LOCK en una tabla, otros usuarios también pueden leer o retener un READ LOCK , pero ningún usuario puede escribir o retener un WRITE LOCK en esa tabla.

Si el motor de almacenamiento predeterminado es InnoDB, MySQL usa automáticamente el bloqueo de nivel de fila para que múltiples transacciones puedan usar la misma tabla simultáneamente para lectura y escritura, sin que se hagan esperar.

Para todos los motores de almacenamiento que no sean InnoDB, MySQL usa el bloqueo de tablas.

Para más detalles sobre el bloqueo de la mesa, vea aquí.

Mysql Locks

Los bloqueos de tablas pueden ser una herramienta importante para ENGINE=MyISAM , pero rara vez son útiles para ENGINE=InnoDB . Si está tentado a utilizar bloqueos de tabla con InnoDB, debe reconsiderar cómo está trabajando con las transacciones.

MySQL permite que las sesiones de los clientes adquieran bloqueos de tablas explícitamente con el fin de cooperar con otras sesiones para acceder a las tablas, o para evitar que otras sesiones modifiquen las tablas durante los períodos en que una sesión requiere acceso exclusivo a ellas. Una sesión puede adquirir o liberar bloqueos solo para sí misma. Una sesión no puede adquirir bloqueos para otra sesión o liberar bloqueos mantenidos por otra sesión.

Los bloqueos se pueden usar para emular transacciones o para obtener más velocidad al actualizar tablas. Esto se explica con más detalle más adelante en esta sección.

Comando: LOCK TABLES table_name READ|WRITE;

puede asignar solo el tipo de bloqueo a una sola tabla;

Ejemplo (READ LOCK):

LOCK TABLES table_name READ;

Ejemplo (BLOQUEO DE ESCRITURA):

LOCK TABLES table_name WRITE;

Para ver si el bloqueo está aplicado o no, use el siguiente comando

SHOW OPEN TABLES;

Para limpiar / eliminar todos los bloqueos, use el siguiente comando:

UNLOCK TABLES;

EJEMPLO:

LOCK TABLES products WRITE:  
INSERT INTO products(id,product_name) SELECT id,old_product_name FROM old_products;
UNLOCK TABLES;

En el ejemplo anterior, cualquier conexión externa no puede escribir datos en la tabla de productos hasta que se desbloquee el producto de la tabla

EJEMPLO:

LOCK TABLES products READ:  
INSERT INTO products(id,product_name) SELECT id,old_product_name FROM old_products;
UNLOCK TABLES;

En el ejemplo anterior, cualquier conexión externa no puede leer ningún dato de la tabla de productos hasta que se desbloquee el producto de la tabla

Bloqueo de nivel de fila

Si las tablas usan InnoDB, MySQL usa automáticamente el bloqueo de nivel de fila para que múltiples transacciones puedan usar la misma tabla simultáneamente para leer y escribir, sin que se hagan esperar.

Si dos transacciones intentan modificar la misma fila y ambas usan bloqueo a nivel de fila, una de las transacciones espera a que la otra se complete.

El bloqueo de nivel de fila también se puede obtener utilizando la SELECT ... FOR UPDATE para cada fila que se espera que se modifique.

Considere dos conexiones para explicar el bloqueo de nivel de fila en detalle

Conexión 1

START TRANSACTION;
SELECT ledgerAmount FROM accDetails WHERE id = 1 FOR UPDATE;

En la conexión 1, el bloqueo de nivel de fila obtenido por la SELECT ... FOR UPDATE .

Conexión 2

UPDATE accDetails SET ledgerAmount = ledgerAmount + 500 WHERE id=1;

Cuando alguien intente actualizar la misma fila en la conexión 2, eso esperará a que la conexión 1 finalice la transacción o se mostrará un mensaje de error según la configuración de innodb_lock_wait_timeout , que de manera predeterminada es de 50 segundos.

Error Code: 1205. Lock wait timeout exceeded; try restarting transaction

Para ver los detalles de este bloqueo, ejecute SHOW ENGINE INNODB STATUS

---TRANSACTION 1973004, ACTIVE 7 sec updating
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 4, OS thread handle 0x7f996beac700, query id 30 localhost root update
UPDATE accDetails SET ledgerAmount = ledgerAmount + 500 WHERE id=1
------- TRX HAS BEEN WAITING 7 SEC FOR THIS LOCK TO BE GRANTED:

Conexión 2

UPDATE accDetails SET ledgerAmount = ledgerAmount + 250 WHERE id=2;
1 row(s) affected

Pero mientras se actualiza alguna otra fila en la conexión 2 se ejecutará sin ningún error.

Conexión 1

UPDATE accDetails SET ledgerAmount = ledgerAmount + 750 WHERE id=1;
COMMIT;
1 row(s) affected

Ahora se libera el bloqueo de fila, porque la transacción se compromete en la Conexión 1.

Conexión 2

UPDATE accDetails SET ledgerAmount = ledgerAmount + 500 WHERE id=1;
1 row(s) affected

La actualización se ejecuta sin ningún error en la Conexión 2 después de que la Conexión 1 liberó el bloqueo de la fila al finalizar la transacción.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow