2010-07-28 19 views
10

¿Qué es el bloqueo en MySQL (o cualquier RDBMS) y cuándo lo usarías? ¡Una explicación Layman con un ejemplo sería genial! Hace¿Qué es el bloqueo en MySQL y cuándo lo usarías?

+0

Es una optimización útil, para usuarios concurrentes: http://www.devshed.com/c/a/MySQL/MySQL-Optimization-part-2/ –

+0

Creo que debería aceptar la respuesta de @Chris. – ripper234

Respuesta

9

Tenemos una cuenta bancaria conjunta con un saldo de $ 200

voy al cajero y le puse la tarjeta en la máquina, la máquina comprueba que tengo un saldo $ 200

Mientras tanto, se van en el banco y pide $ 50, el cajero muestra su cuenta y confirma que tiene el dinero.

que solicitar un retiro de $ 200, la máquina cuenta mi dinero me da $ 200 y establece el equilibrio en $ 0

El cajero cuenta su dinero y los $ 50 da, el sistema actualiza el saldo de la cuenta como $ 150 ($ 200 - retiro de $ 50).

Así que ahora tenemos $ 250 en efectivo y quedan $ 150 en la cuenta. $ 200 de ganancia.

La base de datos debería haber utilizado bloqueos para evitar que ambas transacciones ocurrieran al mismo tiempo.

El problema es que si maneja cada transacción de esa manera perdería la simultaneidad y el rendimiento sufriría, por lo que hay diferentes transaction isolation levels que se utilizan dependiendo del escenario, por ejemplo, puede no importarle que alguien pueda modificar datos que ha sido leído en una transacción.

http://en.wikipedia.org/wiki/Isolation_%28database_systems%29

Usted debe aprender estos y entender los escenarios en los que se aplican.

+0

Gracias @Chris Diver gran explicación! Lo entiendo ahora ;-) – Imran

3

A los pocos días le respondí a question on SO y di un ejemplo que demuestra una situación en la locking permite que varios usuarios insertar simultáneamente filas de una tabla con un incremento id, sin necesidad de utilizar AUTO_INCREMENT.

Considere el siguiente esquema como ejemplo:

CREATE TABLE demo_table (id int) ENGINE=INNODB; 

-- // Add few rows 
INSERT INTO demo_table VALUES (1), (2), (3); 

entonces podemos hacer lo siguiente:

START TRANSACTION; 

-- // Get the MAX(id) so that we increment it by one 
SELECT @x := MAX(id) FROM your_table FOR UPDATE; 

+---------------+ 
| @x := MAX(id) | 
+---------------+ 
|    3 | 
+---------------+ 
1 row in set (0.00 sec) 

El FOR UPDATE sintaxis es lo que realmente pone un bloqueo en las filas leídas por esta consulta.

Sin confirmar la transacción, se inicia otra sesión separada (simulando un usuario concurrente), y hacer lo mismo:

START TRANSACTION; 

-- // Get the MAX(id) as well 
SELECT MAX(id) FROM demo_table FOR UPDATE; 

La base de datos se espere hasta que el bloqueo establecido en la sesión anterior se libera antes de ejecutar este consulta.

Por lo tanto el cambio a la sesión anterior, podemos insertar la nueva fila y confirmar la transacción:

-- // Insert a new row with id = MAX(id) + 1 
INSERT INTO demo_table VALUES (@x + 1); 

COMMIT; 

Después de la primera sesión confirma la transacción, será levantado el bloqueo, y la consulta en la segunda sesión se devuelve:

+---------+ 
| MAX(id) | 
+---------+ 
|  4 | 
+---------+ 
1 row in set (8.19 sec) 

Tenga en cuenta que sin bloqueo, la segunda sesión se habría devuelto de inmediato, pero con 3 como MAX(id) en lugar de 4. Si ambas sesiones fueran a insertar una fila con id de MAX(id) + 1, ambas insertarían id = 4. Puede simular la misma prueba sin el bit FOR UPDATE para ver cómo se maneja esto sin bloqueos.

6

El bloqueo puede ser crucial para evitar que dos usuarios modifiquen datos al mismo tiempo. Puede pensar que es poco probable, pero dependiendo de la aplicación, existe un riesgo significativo si los mismos usuarios cambian frecuentemente los mismos datos.

Imagínese la siguiente situación sin utilizando cerraduras: John abre la pantalla (que no sabe que está usando una base de datos, no es más que un usuario final que está mirando a una pantalla bastante), modifica algunos datos, y luego golpea "Guardar". Digamos que Juan abre la pantalla a las 9:30 y luego guarda los datos a las 9:32.

Sin embargo, Mary abrió exactamente la misma pantalla y el mismo registro a las 9:29. Ella vio en ese momento los mismos datos que John a las 9:30. Luego, actualiza el registro y pulsa "Guardar" a las 9:31.

¿Qué datos se guardaron? ¿John o Mary?

Mary felizmente sigue trabajando en otros registros, y cuando vuelve más tarde para abrir el registro de nuevo, ve que sus cambios se perdieron, ¡y en su lugar ve los cambios de John!

Tenga en cuenta que el bloqueo debe utilizarse con prudencia para evitar efectos secundarios inesperados. Por ejemplo, supongamos que su programa bloquea un registro cada vez que alguien lo abre realiza un cambio. ¿Qué sucede si John bloquea el registro y deja la pantalla de la sesión abierta para almorzar o pierde su conexión? El bloqueo puede permanecer allí, bloqueado e inmutable, durante mucho tiempo, mientras que prohíbe a todos los demás cambiar (o incluso mirar) ese registro. Otra consideración puede ser el rendimiento, debido a que el tiempo para que la base de datos bloquee y desbloquee los registros puede ser notable para una gran cantidad de transacciones.

Entender el bloqueo es crucial para mantener contentos a los usuarios y la integridad de los datos. Por favor mira la documentación.

+0

Gracias @luiscolorado esto realmente ayudó :-) – Imran

+0

El control de versiones de los datos sería una mejor solución para el uso que usted describió. Realmente no puedes mantener un candado durante tanto tiempo ... Lo que haría sería, cuando John acierte guardar, lea la versión de datos +, compárela con lo que le mostró al usuario, y luego haga una ACTUALIZACIÓN sobre los datos que verifica para la versión que acabas de leer hace dos minutos. Si la versión no es la misma, significa que otra persona ha tocado sus datos: debe actualizarla. – ripper234

+2

@ ripper234: es por eso que dije que el bloqueo requiere múltiples consideraciones para el mejor enfoque. Estás en lo correcto para el escenario explicado, y tu sugerencia está bien tomada. No tenía la intención, ni sería posible, de hacer una discusión completa del concepto aquí. El objetivo era proporcionar una respuesta simple y profana. – luiscolorado

Cuestiones relacionadas