Lock:transactionid - Amazon Relational Database Service

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.

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 Server proxy per Amazon RDS.

  • Progettare l'applicazione o il modello di dati per evitare di contendere le istruzioni UPDATE e SELECT … FOR UPDATE. È inoltre possibile ridurre il numero di chiavi esterne a cui accedono le istruzioni SELECT … 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 o ROLLBACK.

  • Cerca percorsi di codice a cui manca COMMIT, ROLLBACK, oppure END.

  • 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 o ROLLBACK.

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.