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.
Context
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
.
Transazioni di lunga durata
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.
Operazioni
Il blocco delle righe è un conflitto tra le istruzioni UPDATE
, SELECT … FOR
UPDATE
, oppure SELECT … FOR KEY SHARE
. 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 Utilizzo di Amazon RDS Proxy .
-
Progettare l'applicazione o il modello di dati per evitare di contendere le istruzioni
UPDATE
eSELECT … 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
COMMIT
oROLLBACK
. -
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 transaction
valido. -
Assicurati che l'applicazione elabori i risultati delle query dopo aver terminato la transazione con
COMMIT
oROLLBACK
.
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.