Informazioni sulla funzione di blocco

Completato

Il controllo della concorrenza multi-versione (MVCC) fornisce le impostazioni di concorrenza appropriate per la maggior parte degli scenari. Tuttavia, se un'applicazione richiede blocchi specifici che controllano esattamente quali righe sono interessate e con un livello di blocco specifico, le modalità di blocco esplicite abilitano questo controllo con granularità fine.

In Database di Azure per PostgreSQL sono disponibili tre tipi di blocchi espliciti: blocchi a livello di tabella, blocchi a livello di riga e blocchi a livello di pagina. La transazione iniziale richiede un blocco e, se accettato, il blocco richiesto diventa il blocco esistente. Se un'altra transazione tenta di escludere un blocco sugli stessi dati, il blocco viene concesso se non è in conflitto con la transazione originale.

Due transazioni, ad esempio, possono eseguire simultaneamente una query sugli stessi dati con un'istruzione SELECT. Queste richieste usano un blocco ACCESS SHARE e sono entrambe consentite. In un altro scenario, una transazione esegue una query sui dati con un'istruzione SELECT e un blocco ACCESS SHARE, ma allo stesso tempo un'altra transazione cerca di rimuovere la stessa tabella. La rimozione di una tabella richiede un blocco ACCESS EXCLUSIVE, che in questo scenario non verrebbe concesso.

Blocchi a livello di tabella

I blocchi a livello di tabella acquisiscono i blocchi su un'intera tabella, anche se hanno ROW nel nome. Il blocco di un'intera tabella potrebbe essere necessario se la tabella stessa venisse modificata oppure potrebbe essere più efficiente rispetto all'estrazione di molti blocchi a livello di riga.

Esistono otto tipi di blocco a livello di tabella in Database di Azure per PostgreSQL e i comandi SQL che acquisiscono questi tipi di blocchi sono:

Modalità di blocco Acquisito da
ACCESS SHARE Comando SELECT
ROW SHARE Comandi SELECT FOR UPDATE e SELECT FOR SHARE
ROW EXCLUSIVE Comandi UPDATE, DELETE e INSERT
SHARE UPDATE EXCLUSIVE Comandi ANALYZE, CREATE INDEX CONCURRENTLY, CREATE STATISTICS, COMMENT ON, REINDEX CONCURRENTLY, alcuni comandi ALTER INDEX e ALTER TABLE e VACUUM (non FULL)
CONDIVIDI Comando CREATE INDEX (non CONCURRENTLY)
SHARE ROW EXCLUSIVE Comando CREATE TRIGGER e alcuni comandi ALTER TABLE
EXCLUSIVE Comando REFRESH MATERIALIZED VIEW CONCURRENTLY
ACCESS EXCLUSIVE Comandi DROP TABLE, REINDEX, TRUNCATE, CLUSTER, REFRESH MATERIALIZED VIEW (non CONCURRENTLY), la maggior parte dei comandi ALTER INDEX e ALTER TABLE e VACUUM FULL

Ogni tipo di blocco esistente blocca l'acquisizione di altri blocchi richiesti. La tabella seguente elenca i blocchi che bloccano l'acquisizione di altri blocchi:

-- ACCESS SHARE esistente ROW SHARE esistente ROW EXCLUSIVE esistente SHARE UPDATE EXCLUSIVE esistente SHARE esistente SHARE ROW EXCL esistente EXCLUSIVE esistente ACCESS EXCLUSIVE esistente
ACCESS SHARE richiesto Bloccati
ROW SHARE richiesto Bloccato Bloccato
ROW EXCLUSIVE richiesto Bloccato Bloccato Bloccato Bloccato
SHARE UPDATE EXCLUSIVE richiesto Bloccato Bloccato Bloccato Bloccato Bloccato
SHARE richiesto Bloccato Bloccato Bloccato Bloccato Bloccato
SHARE ROW EXCLUSIVE richiesto Bloccato Bloccato Bloccato Bloccato Bloccato Bloccato
EXCLUSIVE richiesto Bloccato Bloccato Bloccato Bloccato Bloccato Bloccato Bloccato
ACCESS EXCLUSIVE richiesto Bloccato Bloccato Bloccato Bloccato Bloccato Bloccato Bloccato Bloccato

Blocchi a livello di riga

I blocchi a livello di riga sono più granulari e hanno effetto solo su un'altra transazione che accede alla stessa riga. Questo tipo di blocco migliora la concorrenza, ma l'acquisizione e l'eliminazione di molti blocchi influiscono negativamente sulle prestazioni. I blocchi a livello di riga vengono acquisiti automaticamente da PostgreSQL e non vengono applicati manualmente.

Esistono quattro tipi di blocco a livello di riga in Database di Azure per PostgreSQL e vengono acquisiti a seconda degli altri tipi di blocco che devono essere bloccati:

-- FOR KEY SHARE esistente FOR SHARE esistente FOR NO KEY UPDATE esistente FOR UPDATE esistente
FOR KEY SHARE richiesto Bloccati
FOR SHARE richiesto Bloccato Bloccato
FOR NO KEY UPDATE richiesto Bloccato Bloccato Bloccato
FOR UPDATE richiesto Bloccato Bloccato Bloccato Bloccato

Blocchi a livello di pagina

I blocchi a livello di pagina hanno effetto su una pagina di dati, che in genere è costituita da più righe. Anche se i processi PostgreSQL usano blocchi a livello di pagina, gli sviluppatori di applicazioni in genere non richiedono questo tipo di blocco.

Applicazione manuale dei blocchi e visualizzazione dei blocchi correnti

Per applicare manualmente un blocco a livello di tabella, è possibile usare il comando LOCK con la modalità di blocco richiesta. Il comando LOCK deve trovarsi all'interno di una transazione e i blocchi vengono rilasciati al termine della transazione. Ad esempio:

BEGIN TRANSACTION;
LOCK TABLE humanresources.department IN ROW EXCLUSIVE MODE;
COMMIT;

Per visualizzare i blocchi attualmente presenti nel database, usare pg_locks. Ad esempio, per visualizzare tutti i blocchi correnti, usare il comando seguente:

SELECT * FROM pg_locks;