Serializzabilità e isolamento delle transazioni

Questa pagina descrive il conflitto, la serializzabilità e l'isolamento dei dati transazionali. Per esempi di codice delle transazioni, consulta Transazioni e scritture collettive.

Transazioni e contesa dei dati

Affinché una transazione vada a buon fine, i documenti recuperati dalle operazioni di lettura devono non essere modificati da operazioni esterne alla transazione. Se un'altra operazione tenta di modificare uno di questi documenti, entra in uno stato di contesa dei dati con la transazione.

Conflitto dati
Quando due o più operazioni competono per il controllo dello stesso documento. Ad esempio, una transazione potrebbe richiedere che un documento rimanga coerente mentre un'operazione in parallelo tenta di aggiornare i valori dei campi di quel documento.

Cloud Firestore risolve il conflitto di dati ritardando o non consentendo una delle operazioni. Le librerie client di Cloud Firestore ritentano automaticamente le transazioni non riuscite a causa del conflitto di dati. Dopo un numero finito di tentativi, l'operazione di transazione non va a buon fine e restituisce un messaggio di errore:

ABORTED: Too much contention on these documents. Please try again.

Quando si decide quale operazione non riuscire o ritardare, il comportamento dipende dal tipo di biblioteca client.

  • Gli SDK mobile/web utilizzano controlli della concorrenza ottimistica.

  • Le librerie client server utilizzano controlli di concorrenza pessimistici.

Contesa dei dati negli SDK mobile/web

Gli SDK mobile/web (piattaforme Apple, Android, web, C++) utilizzano controlli della concorrenza ottimistica per risolvere la contesa dei dati.

Controlli della contemporaneità ottimistici
In base all'assunto che la contesa dei dati non sia probabile o che non sia efficiente mantenere i blocchi del database. Le transazioni ottimistiche non utilizzano i blocchi del database per impedire ad altre operazioni di modificare i dati.

Gli SDK mobile/web utilizzano controlli di concorrenza ottimistica, in quanto possono operare in ambienti con latenza elevata e una connessione di rete inaffidabile. Il blocco di documenti in un ambiente ad alta latenza causerebbe troppi errori di contesa dei dati.

Negli SDK mobile/web, una transazione tiene traccia di tutti i documenti che leggi all'interno della transazione. La transazione completa le operazioni di scrittura solo se nessuno di questi documenti è stato modificato durante l'esecuzione della transazione. Se un documento è stato modificato, il gestore della transazione riprova a eseguire la transazione. Se la transazione non riesce a ottenere un risultato chiaro dopo alcuni tentativi, la transazione non va a buon fine a causa della contesa dei dati.

Contesa dei dati nelle librerie client server

Le librerie client del server (C#, Go, Java, Node.js, PHP, Python, Ruby) utilizzano controlli di contemporaneità pessimistici per risolvere il conflitto di dati.

Controlli della concorrenza pessimistici
In base all'ipotesi che sia probabile la contesa dei dati. Le transazioni pessimistiche utilizzano i blocchi del database per impedire ad altre operazioni di modificare i dati.

Le librerie client server utilizzano controlli di concorrenza pessimistici, poiché assumono una latenza ridotta e una connessione affidabile al database.

Nelle librerie client del server, le transazioni applicano blocchi ai documenti che leggono. Il blocco di una transazione su un documento impedisce ad altre transazioni, alle scritture collettive e alle scritture non transazionali di modificare il documento. Una transazione rilascia i blocchi dei documenti al momento del commit. Inoltre, libera i blocchi se scade il tempo di attesa o se non riesce a completare l'operazione per qualsiasi motivo.

Quando una transazione blocca un documento, le altre operazioni di scrittura devono attendere che la transazione rilasci il proprio blocco. Le transazioni acquisiscono i blocchi in ordine cronologico.

Isolamento serializzabile

La contesa dei dati tra le transazioni è strettamente correlata ai livelli di isolamento del database. Il livello di isolamento di un database descrive la capacità del sistema di gestire i conflitti tra operazioni simultanee. Il conflitto deriva dai seguenti requisiti del database:

  • Le transazioni richiedono dati accurati e coerenti.
  • Per utilizzare le risorse in modo efficiente, i database eseguono le operazioni in modo simultaneo.

Nei sistemi con un livello di isolamento basso, un'operazione di lettura all'interno di una transazione potrebbe leggere dati inaccurati da modifiche non committate in un'operazione concorrente.

L'isolamento serializzabile definisce il livello di isolamento più elevato. L'isolamento serializzabile significa che:

  • Puoi assumere che il database esegua le transazioni in serie.
  • Le transazioni non sono interessate da modifiche non impegnate nelle operazioni simultanee.

Questa garanzia deve essere valida anche quando il database esegue più transazioni in parallelo. Il database deve implementare controlli di contemporaneità per risolvere i conflitti che potrebbero inficiare questa garanzia.

Cloud Firestore garantisce l'isolamento serializzabile delle transazioni. Le transazioni in Cloud Firestore vengono serializzate e isolate in base al tempo di impegno.

Isolamento serializzabile in base all'ora del commit

Cloud Firestore assegna a ogni transazione un tempo di commit che rappresenta un singolo momento nel tempo. Quando Cloud Firestore esegue il commit delle modifiche di una transazione nel database, puoi presupporre che tutte le operazioni di lettura e scrittura all'interno della transazione avvengano esattamente al momento del commit.

L'esecuzione effettiva di una transazione richiede un certo periodo di tempo. L'esecuzione di una transazione inizia prima del momento del commit e l'esecuzione di più operazioni può sovrapporsi. Cloud Firestore garantisce l'isolamento serializzabile e garantisce che:

  • Cloud Firestore esegue il commit delle transazioni in ordine in base all'ora del commit.
  • Cloud Firestore isola le transazioni da operazioni simultanee con una durata di commit successiva.

In caso di contesa dei dati tra operazioni concorrenti, Cloud Firestore utilizza i controlli di concorrenza ottimistici e pessimistici per risolvere la contesa.

Isolamento all'interno di una transazione

L'isolamento delle transazioni si applica anche alle operazioni di scrittura all'interno di una transazione. Le query e le letture all'interno di una transazione non vedono i risultati delle scritture precedenti all'interno della transazione. Anche se modifichi o elimini un documento all'interno di una transazione, tutte le letture del documento nella transazione restituiscono la versione del documento al momento del commit, prima delle operazioni di scrittura della transazione. Le operazioni di lettura non restituiscono nulla se il documento non esisteva.

Problemi di contesa dei dati

Per ulteriori informazioni sulle contese dei dati e su come risolverle, consulta la pagina relativa alla risoluzione dei problemi.