sql >> Base de Datos >  >> RDS >> PostgreSQL

Anomalía de sesgo de escritura en Oracle y PostgreSQL no revierte la transacción

En el artículo de 1995, Una crítica de los niveles de aislamiento de ANSI SQL , Jim Gray y compañía, describieron Phantom Read como:

Por lo tanto, una lectura fantasma no significa que simplemente pueda devolver una instantánea desde el inicio de la transacción que se está ejecutando actualmente y fingir que proporcionar el mismo resultado para una consulta lo protegerá contra la anomalía real de lectura fantasma.

En la implementación original de SQL Server 2PL (bloqueo de dos fases), devolver el mismo resultado para una consulta implicaba bloqueos de predicado.

El aislamiento de instantáneas MVCC (control de concurrencia de múltiples versiones) (mal llamado Serializable en Oracle) en realidad no impide que otras transacciones inserten o eliminen filas que coincidan con los mismos criterios de filtrado con una consulta que ya se ejecutó y devolvió un conjunto de resultados en nuestra ejecución actual. transacción.

Por este motivo, podemos imaginar el siguiente escenario en el que queremos aplicar un aumento a todos los empleados:

  1. Tx1:SELECT SUM(salary) FROM employee where company_id = 1;
  2. Tx2:INSERT INTO employee (id, name, company_id, salary) VALUES (100, 'John Doe', 1, 100000);
  3. Tx1:UPDATE employee SET salary = salary * 1.1;
  4. Tx2:COMMIT;
  5. Tx1:COMMIT:

En este escenario, el CEO ejecuta la primera transacción (Tx1), por lo que:

  1. Primero comprueba la suma de todos los salarios de su empresa.
  2. Mientras tanto, el departamento de recursos humanos ejecuta la segunda transacción (Tx2) ya que acaban de contratar a John Doe y le dieron un salario de $ 100k.
  3. El director ejecutivo decide que un aumento del 10 % es factible teniendo en cuenta la suma total de los salarios, sin saber que la suma salarial ha aumentado con 100k.
  4. Mientras tanto, la transacción de recursos humanos Tx2 está confirmada.
  5. Tx1 está confirmado.

¡Auge! El director general ha tomado una decisión basada en una instantánea anterior, otorgando un aumento que podría no ser sostenido por el presupuesto salarial actualizado actual.

Puede ver una explicación detallada de este caso de uso (con muchos diagramas) en la siguiente publicación .

¿Es esto una lectura fantasma o un Escritura sesgada ?

Según Jim Gray y compañía , esta es una lectura fantasma ya que el sesgo de escritura se define como:

En Oracle, Transaction Manager podría o no detectar la anomalía anterior porque no usa bloqueos de predicado o bloqueos de rango de índice (bloqueos de tecla siguiente) , como MySQL.

PostgreSQL logra detectar esta anomalía solo si Bob emite una lectura en la tabla de empleados; de lo contrario, el fenómeno no se evita.

ACTUALIZAR

Inicialmente, supuse que la Serializabilidad también implicaría un orden de tiempo. Sin embargo, como muy bien explicado por Peter Bailis , el orden de los relojes de pared o la capacidad de linealización solo se asumen para la capacidad de serialización estricta.

Por lo tanto, mis suposiciones se hicieron para un sistema serializable estricto. Pero eso no es lo que se supone que ofrece Serializable. El modelo de aislamiento Serializable no garantiza el tiempo, y las operaciones pueden reordenarse siempre que sean equivalentes a un algunos ejecución en serie.

Por lo tanto, de acuerdo con la definición Serializable, tal lectura fantasma puede ocurrir si la segunda transacción no emite ninguna lectura. Pero, en un modelo serializable estricto, el que ofrece 2PL, la lectura fantasma se evitaría incluso si la segunda transacción no emite una lectura contra las mismas entradas que estamos tratando de proteger contra lecturas fantasma.