Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Lock:transactionid
L’evento Lock:transactionid si verifica quando una transazione è in attesa di un blocco a livello di riga.
Versioni del motore supportate
Queste informazioni relative all'evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL.
Contesto
L'evento Lock:transactionid si verifica quando una transazione sta tentando di acquisire un blocco a livello di riga già concesso a una transazione in esecuzione contemporaneamente. La sessione che mostra il l'evento di attesa Lock:transactionid è bloccato a causa di questo blocco. Dopo che la transazione di blocco termina in un’istruzione COMMIT o ROLLBACK, la transazione bloccata può procedere.
La semantica multiversione di controllo della concorrenza di RDS per PostgreSQL garantisce che i lettori non bloccano gli scrittori e gli scrittori non bloccano i lettori. Affinché si verifichino conflitti a livello di riga, le transazioni bloccate e bloccate devono emettere dichiarazioni in conflitto dei seguenti tipi:
-
UPDATE -
SELECT … FOR UPDATE -
SELECT … FOR KEY SHARE
L’istruzione SELECT … FOR KEY SHARE è un caso speciale. Il database utilizza la clausola FOR KEY
SHARE per ottimizzare le prestazioni dell'integrità referenziale. Un blocco a livello di riga su una fila può bloccare i comandi INSERT, UPDATE, e DELETE su altre tabelle che fanno riferimento alla riga.
Probabili cause di aumento delle attese
Quando questo evento appare più del normale, la causa è in genere un’istruzione UPDATE, SELECT …
FOR UPDATE, oppure SELECT … FOR KEY SHARE combinate con le seguenti condizioni.
Elevata concorrenza
RDS per PostgreSQL può utilizzare la semantica di blocco granulare a livello di riga. La probabilità di conflitti a livello di riga aumenta quando vengono soddisfatte le seguenti condizioni:
-
Un carico di lavoro altamente simultaneo è conteso per le stesse righe.
-
Aumenta la concorrenza.
Inattivo in transazione
A volte la colonna pg_stat_activity.state mostra il valore idle in transaction. Questo valore viene visualizzato per le sessioni che hanno avviato una transazione, ma non hanno ancora emesso un COMMIT o ROLLBACK. Se il valore pg_stat_activity.state non è active, la query mostrata in pg_stat_activity è la versione più recente a terminare l’esecuzione. La sessione di blocco non sta elaborando attivamente una query perché una transazione aperta contiene un blocco.
Se una transazione inattiva ha acquisito un blocco a livello di riga, potrebbe impedire ad altre sessioni di acquisirlo. Questa condizione porta al frequente verificarsi dell'evento di attesa Lock:transactionid. Per diagnosticare il problema, esaminare l'output da pg_stat_activity e pg_locks.
Long-running transazioni
Le transazioni che vengono eseguite a lungo ricevono blocchi per un lungo periodo di tempo. Questi blocchi a tenuta lunga possono impedire l'esecuzione di altre transazioni.
Azioni
Row-locking è un conflitto tra UPDATE o SELECT … FOR KEY SHARE affermazioni. SELECT … FOR
UPDATE Prima di tentare una soluzione, scopri quando queste istruzioni sono in esecuzione sulla stessa riga. Utilizzare queste informazioni per scegliere una strategia descritta nelle sezioni seguenti.
Argomenti
Rispondere a un'elevata concorrenza
Se il problema è la concorrenza, prova una delle seguenti tecniche:
-
Riduci la concorrenza nell'applicazione. Ad esempio, diminuisci il numero di sessioni attive.
-
Implementa un pool di connessioni. Per informazioni su come mettere in pool le connessioni con RDS Proxy, vedere Proxy Amazon RDS Proxy .
-
Progettare l'applicazione o il modello di dati per evitare di contendere le istruzioni
UPDATEeSELECT … FOR UPDATE. È inoltre possibile ridurre il numero di chiavi esterne a cui accedono le istruzioniSELECT … FOR KEY SHARE.
Rispondere alle transazioni inattive
Se pg_stat_activity.state mostra idle in transaction, utilizza le seguenti strategie:
-
Attiva autocommit laddove possibile. Questo approccio impedisce alle transazioni di bloccare altre transazioni durante l'attesa di un
COMMIToROLLBACK. -
Cerca percorsi di codice a cui manca
COMMIT,ROLLBACK, oppureEND. -
Assicurati che la logica di gestione delle eccezioni nell'applicazione abbia sempre un percorso per un
end of transactionvalido. -
Assicurati che l'applicazione elabori i risultati delle query dopo aver terminato la transazione con
COMMIToROLLBACK.
Rispondere alle transazioni di lunga durata
Se le transazioni di lunga durata causano il frequente verificarsi di Lock:transactionid, prova le seguenti strategie:
-
Tieni i blocchi di riga fuori dalle transazioni di lunga durata.
-
Limita la durata delle query implementando autocommit quando possibile.