sql >> Base de Datos >  >> RDS >> Mysql

Cuando se usa el bloqueo FOR UPDATE de MySQL, ¿qué se bloquea exactamente?

¿Por qué no lo intentamos?

Configurar la base de datos

CREATE DATABASE so1;
USE so1;
CREATE TABLE notification (`id` BIGINT(20), `date` DATE, `text` TEXT) ENGINE=InnoDB;
INSERT INTO notification(id, `date`, `text`) values (1, '2011-05-01', 'Notification 1');
INSERT INTO notification(id, `date`, `text`) values (2, '2011-05-02', 'Notification 2');
INSERT INTO notification(id, `date`, `text`) values (3, '2011-05-03', 'Notification 3');
INSERT INTO notification(id, `date`, `text`) values (4, '2011-05-04', 'Notification 4');
INSERT INTO notification(id, `date`, `text`) values (5, '2011-05-05', 'Notification 5');

Ahora, inicie dos conexiones de base de datos

Conexión 1

BEGIN;
SELECT * FROM notification WHERE `date` >= '2011-05-03' FOR UPDATE;

Conexión 2

BEGIN;

Si MySQL bloquea todas las filas, la siguiente declaración bloquearía. Si solo bloquea las filas que devuelve, no debería bloquear.

SELECT * FROM notification WHERE `date` = '2011-05-02' FOR UPDATE;

Y de hecho bloquea.

Curiosamente, tampoco podemos agregar registros que se leerían, es decir,

INSERT INTO notification(id, `date`, `text`) values (6, '2011-05-06', 'Notification 6');

bloques también!

No puedo estar seguro en este momento si MySQL sigue adelante y bloquea toda la tabla cuando un cierto porcentaje de filas están bloqueadas, o si es realmente inteligente para asegurarse de que el resultado de SELECT ... FOR UPDATE la consulta nunca puede ser modificada por otra transacción (con un INSERT , UPDATE o DELETE ) mientras se mantiene el bloqueo.