uncommitted transaction read oracle isolation-level transaction-isolation

oracle - set transaction isolation level read uncommitted



¿Cuál es la diferencia entre lectura no repetible y lectura fantasma? (7)

¿Cuál es la diferencia entre lectura no repetible y lectura fantasma?

He leído el artículo sobre aislamiento (sistemas de bases de datos) de Wikipedia , pero tengo algunas dudas. En el siguiente ejemplo, ¿qué sucederá: la lectura no repetible y la lectura fantasma ?

Transacción A

SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1 SALIDA:

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 debería usarse? ¿Y por qué?


Creo que hay alguna diferencia entre lectura no repetible y lectura fantasma.

El no repetible significa que hay operaciones de acarreo A y B. si B puede notar la modificación de A, entonces puede que suceda lectura sucia, por lo que dejamos que B note la modificación de A después de la confirmación.

Hay un nuevo problema: dejamos que B note la modificación de A después de la confirmación, significa que A modifica un valor de la fila que B está reteniendo, en algún momento B leerá nuevamente la fila, por lo que B obtendrá un nuevo valor diferente la primera vez que obtener, lo llamamos No repetible, para tratar el problema, dejamos que el B recuerde algo (porque aún no sé qué se recordará) cuando B comience.

Pensemos en la nueva solución, podemos notar que también hay un problema nuevo, porque dejamos que B recuerde algo, así que pase lo que pase en A, la B no puede verse afectada, pero si B quiere insertar algunos datos en la tabla y B verifique la tabla para asegurarse de que no haya ningún registro, pero esta información ha sido insertada por A, entonces tal vez ocurra algún error. Lo llamamos Phantom-read.


En un sistema con lecturas no repetibles, el resultado de la segunda consulta de la Transacción A reflejará la actualización en la Transacción B; verá la nueva cantidad.

En un sistema que permite lecturas fantasmas, si la Transacción B fuera a insertar una nueva fila con ID = 1, la Transacción A verá la nueva fila cuando se ejecute la segunda consulta; es decir, las lecturas fantasmas son un caso especial de lectura no repetible.


Hay una diferencia en la implementación entre estos dos tipos de niveles de aislamiento.
Para "lectura no repetible", es necesario el bloqueo de filas.
Para "lectura fantasma", se necesita un bloqueo de alcance, incluso un bloqueo de mesa.
Podemos implementar estos dos niveles mediante el uso two-phase-locking protocolo de two-phase-locking .


La respuesta aceptada indica, sobre todo, que la llamada distinción entre los dos no es para nada significativa.

Si "una fila se recupera dos veces y los valores dentro de la fila difieren entre lecturas", entonces no son la misma fila (no es la misma tupla en el habla correcta de RDB) y entonces, por definición, también es el caso que "la colección de las filas devueltas por la segunda consulta son diferentes de las primeras ".

En cuanto a la pregunta "qué nivel de aislamiento se debe utilizar", cuanto más tus datos sean de vital importancia para alguien, en algún lugar, más seria el hecho de que Serializable es tu única opción razonable.


Lectura sucia: lee datos SIN COMPROMISO de otra transacción.

Lectura no repetible: lea datos COMPROMETIDOS desde una consulta de ACTUALIZACIÓN desde otra transacción.

Phantom read: lee los datos COMMITED de una consulta INSERT o DELETE de otra transacción.

Tenga en cuenta que las ACTUALIZACIONES pueden ser un trabajo más frecuente en determinadas aplicaciones en lugar de las INSERTAS o LAS ELIMINACIONES reales; en estos casos, el peligro de lecturas no repetibles permanece solo, las lecturas fantasmas no son posibles en esos casos. Esto explica por qué las ACTUALIZACIONES se tratan de forma diferente a INSERT-DELETE y la anomalía en cuestión también recibe un nombre diferente.

También hay un costo de procesamiento adicional asociado con el manejo de INSERT-DELETES, en lugar de simplemente manejar las ACTUALIZACIONES.

El nivel de aislamiento TRANSACTION_READ_UNCOMMITTED no impide nada. Es el nivel de aislamiento cero.

El nivel de aislamiento TRANSACTION_READ_COMMITTED evita solo uno, es decir. Dirty lee.

El nivel de aislamiento TRANSACTION_REPEATABLE_READ previene dos anomalías: lecturas sucias y lecturas no repetibles.

El nivel de aislamiento TRANSACTION_SERIALIZABLE evita las tres anomalías: lecturas sucias, lecturas no repetibles y lecturas Phantom.

Entonces, ¿por qué no simplemente establecer la transacción SERIALIZABLE en todo momento?

Bueno, la respuesta a la pregunta anterior es: la configuración de SERIALIZABLE hace que las transacciones sean muy lentas, lo que de nuevo no queremos.

De hecho, el consumo de tiempo de transacción está en la siguiente tasa:

SERIALIZABLE> REPEATABLE_READ> READ_COMMITTED> READ_UNCOMMITTED.

Entonces la configuración READ_UNCOMMITTED es la más rápida.

En realidad, necesitamos analizar el caso de uso y decidir un nivel de aislamiento para optimizar el tiempo de transacción y también evitar la mayoría de las anomalías.

Tenga en cuenta que las bases de datos tienen de forma predeterminada la configuración REPEATABLE_READ.


Una manera simple en la que me gusta pensar es:

Tanto las lecturas fantasmas como no repetibles tienen que ver con las operaciones de modificación de datos de una transacción diferente, que se cometieron después de que comenzó su transacción, y luego se leen por su transacción.

Las lecturas no repetibles son cuando su transacción lee ACTUALIZACIONES comprometidas de otra transacción. La misma fila ahora tiene valores diferentes a los que tenía cuando comenzó su transacción.

Las lecturas fantasmas son similares, pero al leer INSERCIONES comprometidas y / o BORRAR de otra transacción. Hay nuevas filas o filas que han desaparecido desde que comenzó la transacción.

Las lecturas sucias son similares a las lecturas fantasma y no repetibles, pero se refieren a 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 curso", que pueden no estar completos, y es posible que nunca se hayan confirmado.


De Wikipedia (que tiene ejemplos geniales y detallados para esto):

Se produce una lectura no repetible, cuando durante el curso de una transacción, una fila se recupera dos veces y los valores dentro de la fila difieren entre 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 devuelta por la segunda consulta es diferente de la primera.

Ejemplos simples:

  • El usuario A ejecuta la misma consulta dos veces.
  • Mientras tanto, 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 por segunda vez.
  • Phantom read: todas las filas de la consulta tienen el mismo valor antes y después, pero se están seleccionando diferentes filas (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 usar?

Qué nivel de aislamiento necesita depende de su aplicación. Hay un alto costo para un nivel de aislamiento "mejor" (como concurrencia reducida).

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 tanto, si eso es un problema, es posible que desee tener un nivel de aislamiento que lo impida. En Oracle, la transacción A también podría emitir un SELECCIONAR PARA ACTUALIZAR, luego la transacción B no puede cambiar la fila hasta que A finalice.