¿Lectura no repetible versus lectura fantasma?
¿ Cuál es la diferencia entre lectura no repetible y lectura fantasma ?
He leído el artículo Aislamiento (sistemas de bases de datos) de Wikipedia , pero tengo algunas dudas. En el siguiente ejemplo, ¿qué pasará: la lectura no repetible y la lectura fantasma ?
#### Transacción A
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
#### PRODUCCIÓN:
1----MIKE------29019892---------5000
#### Transacción B
UPDATE USERS SET amount=amount+5000 where ID=1 AND accountno=29019892;
COMMIT;
#### Transacción A
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
Otra duda es, en el ejemplo anterior, ¿qué nivel de aislamiento se debe utilizar? ¿Y por qué?
De Wikipedia (que tiene ejemplos excelentes y detallados para esto):
Una lectura no repetible ocurre cuando, durante el curso de una transacción, una fila se recupera dos veces y los valores dentro de la fila difieren entre las lecturas.
y
Una lectura fantasma ocurre cuando, en el curso de una transacción, se ejecutan dos consultas idénticas y la colección de filas devueltas por la segunda consulta es diferente de la primera.
Ejemplos simples:
- El usuario A ejecuta la misma consulta dos veces.
- En el medio, el usuario B ejecuta una transacción y se compromete.
- Lectura no repetible: la fila A que el usuario A ha consultado tiene un valor diferente la segunda vez.
- Lectura fantasma: todas las filas de la consulta tienen el mismo valor antes y después, pero se seleccionan filas diferentes (porque B ha eliminado o insertado algunas). Ejemplo:
select sum(x) from table;
devolverá un resultado diferente incluso si ninguna de las filas afectadas se ha actualizado, si se han agregado o eliminado filas.
En el ejemplo anterior, ¿qué nivel de aislamiento utilizar?
El nivel de aislamiento que necesita depende de su aplicación. Un nivel de aislamiento "mejor" (como una concurrencia reducida) tiene un alto costo.
En su ejemplo, no tendrá una lectura fantasma, porque selecciona solo de una sola fila (identificada por la clave principal). Puede tener lecturas no repetibles, por lo que si eso es un problema, es posible que desee tener un nivel de aislamiento que lo evite. En Oracle, la transacción A también podría emitir una SELECCIONAR PARA ACTUALIZAR, luego la transacción B no puede cambiar la fila hasta que A haya terminado.
Una forma sencilla en la que me gusta pensarlo es:
Tanto las lecturas no repetibles como las fantasmas tienen que ver con operaciones de modificación de datos de una transacción diferente, que se confirmaron después de que comenzó su transacción y luego fueron leídas por su transacción.
Las lecturas no repetibles son cuando su transacción lee ACTUALIZACIONES confirmadas de otra transacción. La misma fila ahora tiene valores diferentes a los que tenía cuando comenzó su transacción.
Las lecturas fantasma son similares, pero cuando se leen INSERTS y/o DELETES confirmados de otra transacción. Hay filas nuevas o filas que han desaparecido desde que inició la transacción.
Las lecturas sucias son similares a las lecturas no repetibles y fantasmas, pero se relacionan con la lectura de datos NO COMPROMETIDOS y ocurren cuando se lee una ACTUALIZACIÓN, INSERCIÓN o ELIMINACIÓN de otra transacción, y la otra transacción aún NO ha confirmado los datos. Está leyendo datos "en progreso", que pueden no estar completos y es posible que nunca se confirmen.