2015-10-08 10 views
5

La maggior parte degli RDBMS consente di acquisire una condivisione sul blocco esclusivo sulle righe selezionate. Ad esempio, PostgreSQL ha una sintassi del genere:Perché i blocchi dei predicati non possono essere acquisiti tramite una sintassi esplicita della query di blocco

SELECT * 
FROM post 
WHERE id=10 
FOR SHARE; 

Utilizzando PER SHARE, si può acquisire blocchi condivisa anche in livello di isolamento READ_COMMITTED e fenomeni di lettura non ripetibili può essere impedito senza utilizzare l'isolamento della transazione REPEATABLE_READ.

Ma per evitare letture fantasma, SERIALIZABLE è l'unico modo per farlo. Perché non esiste una sintassi di blocco esplicita per acquisire anche un blocco di predicati?

A mia conoscenza, non ricordo di aver visto alcun costrutto simile in Oracle, SQL Server, MySQL o PostgreSQL.

+0

come ricordo per SHARE ha lo stesso semantico di SELECT FOR UPDATE. si riceve READ LOCK per la lettura su tutte le tabelle coinvolte per la selezione. d'altra parte, SERIALIZABLE lvl fornisce anche WRITE LOCK. inoltre, SELECT FOR UPDATE ha la stessa semantica in Oracle, ad es. – ivanenok

+1

PER SHARE acquisisce un blocco di lettura, mentre FOR UPDATE fornisce invece un blocco di scrittura. Quando si utilizza SERIALIZABLE, il database acquisisce entrambi i blocchi SHARED (per impedire le letture fuzzy) su tutte le righe recuperate e anche i blocchi intervallo/predicato (per evitare letture fantasma). –

+1

Perché si desidera imporre un livello di isolamento della transazione a ogni query anziché utilizzare solo il livello di isolamento della transazione? In Oracle, è possibile utilizzare sempre una query di flashback su un SCN per evitare letture fantasma (che è ciò che Oracle sta facendo sotto le copertine se si imposta il livello di isolamento della transazione su serializzabile). Ciò non richiederebbe alcun tipo di blocco o alcun tipo di blocco di altre sessioni. Ma non avrebbe lo stesso comportamento di lanciare un ORA-08177: Impossibile serializzare l'accesso per questo errore di transazione per modifiche non serializzabili. –

risposta

2

In PostreSQL Il livello di isolamento serializzabile si basa sul cosiddetto Serializable Snapshot Isolation, che utilizza i blocchi del predicato non per il blocco effettivo, ma per il monitoraggio di condizioni che potrebbero creare un'anomalia di serializzazione. Questo meccanismo funziona solo a livello serializzabile; non è possibile utilizzare i blocchi di predicato ai livelli inferiori.

Ma per evitare letture fantasma, in PostgreSQL è sufficiente solo il livello di isolamento Leggi ripetuto (nonostante ciò che lo standard SQL dice sui livelli di isolamento). Vedi the documentation per i dettagli.

Per quanto riguarda Oracle, non ha alcun blocco di predicato. Il suo livello di isolamento Serializable utilizza l'isolamento dell'istantanea (lo stesso di Ripetibile Read in PostgreSQL), che impedisce le letture fantasma ma consente other serialization anomalies.

Non ho informazioni su SQL Server e MySQL.

1

Lo standard non specifica i blocchi del predicato o che il blocco del predicato deve essere utilizzato per implementare SERIALIZABLE. Specifica solo le anomalie SERIALIZABLE deve impedire ... e la maggior parte dei DBMS in realtà non si conformano pienamente a questo.

Nel caso di PostgreSQL non esiste una sintassi di blocco del predicato esplicito perché non ci sono blocchi di predicato. PostgreSQL utilizza qualcosa di simile al blocco ottimistico per SERIALIZABLE, dove tiene traccia delle dipendenze tra le transazioni e si interrompe se rileva una dipendenza circolare. Questo non segue la semantica di un blocco e non sarebbe molto utile da fare esplicitamente.

Problemi correlati