InnoDB debe proteger contra lecturas fantasmas, como otros han escrito.
Pero InnoDB tiene un comportamiento extraño diferente relacionado con el bloqueo. Cuando una consulta adquiere un bloqueo, siempre adquiere el bloqueo en la versión más reciente de la fila. A fin de tratar el siguiente
CREATE TABLE foo (i INT PRIMARY KEY, val INT);
INSERT INTO foo (i, val) VALUES (1, 10), (2, 20), (3, 30);
Luego, en dos sesiones simultáneas (abrir dos ventanas de terminal):
-- window 1 -- window 2
START TRANSACTION;
START TRANSACTION;
SELECT * FROM foo;
UPDATE foo SET val=35 WHERE i=3;
SELECT * FROM foo;
Esto debería mostrar val = 10, 20, 30 en ambos SELECTs, ya REPETIBLE-LEER significa la La segunda ventana solo ve los datos tal como existían cuando comenzó su transacción.
Sin embargo:
SELECT * FROM foo FOR UPDATE;
La segunda ventana de espera para adquirir el bloqueo en fila 3.
COMMIT;
Ahora el SELECT en el segundo acabados de ventana, y muestra las filas con val = 10, 20 , 35, porque el bloqueo de la fila hace que SELECT vea la versión confirmada más reciente. Las operaciones de bloqueo en InnoDB actúan como si se ejecutaran bajo READ-COMMITTED, independientemente del nivel de aislamiento de la transacción.
Incluso puede alternar:
SELECT * FROM foo;
SELECT * FROM foo FOR UPDATE;
SELECT * FROM foo;
SELECT * FROM foo FOR UPDATE;
Gracias. Eso más o menos lo explica. Tendré que analizar este "problema" en uno o dos meses. Y el llamado problema solo está mostrando que puede suceder ... en otro tipo de base de datos. – Erik
@deFreitas No escribí esta respuesta. Solo lo edité. Debería redirigir su comentario a danihp que escribió la respuesta. – Gili
Mi error, el comentario fue dirigido a @danihp – deFreitas