Documentazione di PostgreSQL 9.0 > Il linguaggio SQL > Controllo concorrente > Controlli di consistenza dei dati a livello di applicazione
PrecedenteLock esplicitoLocking e indiciSuccessivo

13.4. Controlli di consistenza dei dati a livello di applicazione

Dato che le letture in PostgreSQL™ non eseguono lock dei dati, malgrado il livello di isolamento transazionale, i dati letti da una transazione possono essere sovrascritti da un'altra transazione concorrente. In altre parole, se una riga viene restituita da SELECT non significa che la riga è ancora la corrente nell'istante che è restituita (per es., a volte dopo che la query attuale è cominciata). La riga potrebbe essere stata modificata o cancellata da una transazione che ha già fatto un commit dopo che la SELECT è iniziata. Anche se la riga è comunque valida «ora», potrebbe essere cambiato o cancellato prima che la transazione corrente faccia un commit o un rollback.

Un altro modo di pensare a questo è che ogni transazione vede un'istantanea del contenuto del database, e concorrentemente transazioni in esecuzione potrebbero vedere differenti istantanee. Così l'intero concetto di «ora» in qualche modo è comunque non ben definito. Normalmente non è un gran problema se le applicazioni client sono isolate l'una dall'altra, me se i client possono comunicare attraverso canali esterni al database allora potrebbe verificarsi molta confusione.

Per assicurare la validità della riga corrente e proteggerla rispetto ad aggiornamenti concorrenti si deve usare SELECT FOR UPDATE, SELECT FOR SHARE o un'istruzione LOCK TABLE appropriata. (SELECT FOR UPDATE e SELECT FOR SHARE eseguono un lock solamente sulle righe restituite rispetto a agiornamenti concorrenti, mentre LOCK TABLE esegue un lock sull'intera tabella). Questo dovrebbe essere messo in conto quando si portano applicazioni a PostgreSQL™ da altri ambienti.

I controlli di validità globale richiedono ulteriori considerazioni con MVCC. Per esempio, un'applicazione bancaria potrebbe voler controllare che la somma di tutti i crediti in una tabella uguagli la somma dei debiti in un'altra tabella, mentre entrambe le tabelle vengono aggiornate attivamente. Confrontare i risultati di due comandi SELECT sum(...) successivi non funzionerà correttamente in modalità Read Committed, dato che la seconda query probabilmente includerà i risultati di transazioni non contate dalla prima. Fare le due somme in una singola transazione serializzabile fornirà una fotografia accurata solo degli effetti di transazioni che hanno fatto un commit prima che la transazione serializzabile cominciasse - ma si potrebbe legittimamente meravigliarsi se la risposta è ancora rilevante al momento della consegna. Se la transazione serializzabile da sola ha applicato alcuni cambiamenti prima di tentare di fare un controllo di consistenza, l'utilità di questo controllo è cmunque molto dibattuta, dato che adesso include alcuni ma non tutti i cambiamenti post-transazione. In quei casi una persona prudente potrebbe desiderare di fare un lock su tutte le tabelle necessarie al controllo, per ottenere un'immagine indiscutibile della realtà corrente. Un lock in modalità SHARE (o superiore) garantisce che non ci siano cambiamenti non sottoposti a commit nella tabella che ha il lock, diversi da quelli della transazione corrente.

Notare anche che se si fa affidamento sul locking esplicito per prevenire cambiamenti concorrenti, di dovrebbe usare o la modalità Read Committed, altrimenti in modalità Serializable fare attenzione a ottenere i lock prima di eseguire le query. Un lock ottenuto da una transazione serializzabile garantisce che nessun'altra transazione che modifichi la tabella sia in esecuzione, ma se l'istantanea vista dalla transazione precede l'acquisizione del lock, potrebbe anticipare alcuni cambiamenti appena sottoposti a commit nella tabella. Un'istantanea di transazione serializzabile attualmente viene bloccata all'inizio del suo primo comando di interrogazione o modifica dei dati (SELECT, INSERT, UPDATE o DELETE), così è possibile ottenere lock esplicitamente prima che l'istantanea sia "congelata".

Documentazione di PostgreSQL 9.0 > Il linguaggio SQL > Controllo concorrente > Controlli di consistenza dei dati a livello di applicazione
PrecedenteLock esplicitoLocking e indiciSuccessivo