PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Write Skew anomaly in Oracle e PostgreSQL non esegue il rollback della transazione

Nel documento del 1995, Una critica ai livelli di isolamento ANSI SQL , Jim Gray e co, hanno descritto Phantom Read come:

Pertanto, una lettura fantasma non significa che puoi semplicemente restituire un'istantanea dall'inizio della transazione attualmente in esecuzione e fingere che fornire lo stesso risultato per una query ti proteggerà dall'effettiva anomalia di lettura fantasma.

Nell'implementazione originale di SQL Server 2PL (Blocco a due fasi), la restituzione dello stesso risultato per una query implicava i blocchi predicati.

L'isolamento snapshot MVCC (Multi-Version Concurrency Control) (erroneamente denominato Serializable in Oracle) non impedisce effettivamente ad altre transazioni di inserire/eliminare righe che corrispondono agli stessi criteri di filtraggio con una query che è già stata eseguita e ha restituito un set di risultati nella nostra esecuzione corrente transazione.

Per questo possiamo immaginare il seguente scenario in cui vogliamo applicare un aumento a tutti i dipendenti:

  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:

In questo scenario, il CEO esegue la prima transazione (Tx1), quindi:

  1. Prima controlla la somma di tutti gli stipendi della sua azienda.
  2. Nel frattempo, il dipartimento delle risorse umane esegue la seconda transazione (Tx2) poiché è appena riuscito ad assumere John Doe e gli ha dato uno stipendio di 100.000 $.
  3. Il CEO decide che un aumento del 10% è fattibile tenendo conto della somma totale degli stipendi, non sapendo che la somma dello stipendio è aumentata di 100k.
  4. Nel frattempo, la transazione HR Tx2 è impegnata.
  5. Tx1 è impegnato.

Boom! Il CEO ha preso una decisione su una vecchia istantanea, dando un aumento che potrebbe non essere sostenuto dall'attuale budget salariale aggiornato.

Puoi visualizzare una spiegazione dettagliata di questo caso d'uso (con molti diagrammi) nel il seguente post .

È una lettura fantasma o un Scrivi obliqua ?

Secondo Jim Gray e compagni , questa è una lettura fantasma poiché lo Skew di scrittura è definito come:

In Oracle, il Transaction Manager potrebbe rilevare o meno l'anomalia di cui sopra perché non utilizza blocchi dei predicati o blocchi dell'intervallo dell'indice (blocchi del tasto successivo) , come MySQL.

PostgreSQL riesce a rilevare questa anomalia solo se Bob emette una lettura sulla tabella dipendente, altrimenti il ​​fenomeno non viene impedito.

AGGIORNAMENTO

Inizialmente, presumevo che la serializzabilità implicasse anche un ordinamento temporale. Tuttavia, come spiega molto bene Peter Bailis , l'ordinazione dell'orologio da parete o la linearizzabilità sono presupposti solo per la serializzabilità rigorosa.

Pertanto, le mie ipotesi sono state fatte per un sistema Strict Serializable. Ma non è ciò che Serializable dovrebbe offrire. Il modello di isolamento serializzabile non fornisce garanzie sul tempo e le operazioni possono essere riordinate purché siano equivalenti a alcuni esecuzione seriale.

Pertanto, secondo la definizione Serializzabile, tale lettura fantasma può verificarsi se la seconda transazione non emette alcuna lettura. Ma, in un modello Strict Serializable, quello offerto da 2PL, la lettura fantasma sarebbe impedita anche se la seconda transazione non emette una lettura rispetto alle stesse voci che stiamo cercando di proteggere dalle letture fantasma.