PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Anomalia de Skew de gravação no Oracle e PostgreSQL não reverte a transação


No artigo de 1995, Uma crítica aos níveis de isolamento SQL ANSI , Jim Gray e companhia, descreveram Phantom Read como:

Portanto, uma leitura fantasma não significa que você pode simplesmente retornar um instantâneo a partir do início da transação atualmente em execução e fingir que fornecer o mesmo resultado para uma consulta irá protegê-lo contra a anomalia real da leitura fantasma.

Na implementação original do SQL Server 2PL (Two-Phase Locking), retornar o mesmo resultado para uma consulta implicava Predicate Locks.

O isolamento de instantâneo MVCC (Multi-Version Concurrency Control) (erroneamente chamado de Serializable no Oracle) não impede que outras transações insiram/excluam linhas que correspondam aos mesmos critérios de filtragem com uma consulta que já foi executada e retornou um conjunto de resultados em nossa execução atual transação.

Por esse motivo, podemos imaginar o seguinte cenário em que queremos aplicar um aumento a todos os funcionários:
  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:

Nesse cenário, o CEO executa a primeira transação (Tx1), portanto:
  1. Ela primeiro verifica a soma de todos os salários da empresa.
  2. Enquanto isso, o departamento de RH executa a segunda transação (Tx2), pois acabou de contratar John Doe e deu a ele um salário de 100 mil dólares.
  3. O CEO decide que um aumento de 10% é viável levando em consideração a soma total dos salários, sem saber que a soma salarial aumentou em 100 mil.
  4. Enquanto isso, a transação de RH Tx2 é confirmada.
  5. Tx1 está confirmado.

Estrondo! O CEO tomou uma decisão sobre um instantâneo antigo, dando um aumento que pode não ser sustentado pelo atual orçamento salarial atualizado.

Você pode ver uma explicação detalhada deste caso de uso (com muitos diagramas) na a seguinte postagem .

É uma leitura fantasma ou um Escrever desvio ?

De acordo com Jim Gray e companhia , este é um Phantom Read, pois o Write Skew é definido como:

No Oracle, o Transaction Manager pode ou não detectar a anomalia acima porque não usa bloqueios de predicado ou bloqueios de intervalo de índice (bloqueios de próxima tecla) , como o MySQL.

O PostgreSQL consegue detectar essa anomalia apenas se Bob emitir uma leitura na tabela de funcionários, caso contrário, o fenômeno não é evitado.

ATUALIZAÇÃO


Inicialmente, eu estava assumindo que a serialização também implicaria em um pedido de tempo. No entanto, como muito bem explicado por Peter Bailis , ordenação de relógio de parede ou Linearização é assumida apenas para Serializabilidade estrita.

Portanto, minhas suposições foram feitas para um sistema Strict Serializable. Mas não é isso que o Serializable deve oferecer. O modelo de isolamento serializável não oferece garantias sobre o tempo, e as operações podem ser reordenadas desde que sejam equivalentes a algumas execução em série.

Portanto, de acordo com a definição Serializable, tal Phantom Read pode ocorrer se a segunda transação não emitir nenhuma leitura. Mas, em um modelo Strict Serializable, o oferecido pelo 2PL, o Phantom Read seria impedido mesmo que a segunda transação não emitisse uma leitura nas mesmas entradas que estamos tentando proteger contra leituras fantasmas.